source: trunk/include/samhain.h@ 556

Last change on this file since 556 was 488, checked in by katerina, 9 years ago

Fix for tickets #386 (silent check) and #387 (linux audit support).

File size: 15.5 KB
RevLine 
[1]1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999 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#ifndef SAMHAIN_H
21#define SAMHAIN_H
22
23#include <sys/types.h>
24#include "slib.h"
25
26#ifdef SH_ENCRYPT
27#include "rijndael-api-fst.h"
28#endif
29
[481]30#if defined(__GNUC__) && (__GNUC__ >= 4)
31#define SH_GNUC_SENTINEL __attribute__((__sentinel__))
32#else
33#define SH_GNUC_SENTINEL
34#endif
35
36#if defined(__GNUC__) && (__GNUC__ >= 3)
37#undef SH_GNUC_PURE
38#define SH_GNUC_PURE __attribute__((pure))
39#undef SH_GNUC_CONST
40#define SH_GNUC_CONST __attribute__((const))
41#undef SH_GNUC_NORETURN
42#define SH_GNUC_NORETURN __attribute__((noreturn))
43#undef SH_GNUC_MALLOC
44#define SH_GNUC_MALLOC __attribute__((malloc))
45#else
46#undef SH_GNUC_PURE
47#define SH_GNUC_PURE
48#undef SH_GNUC_CONST
49#define SH_GNUC_CONST
50#undef SH_GNUC_NORETURN
51#define SH_GNUC_NORETURN
52#undef SH_GNUC_MALLOC
53#define SH_GNUC_MALLOC
54#endif
55
[1]56/**************************************************
57 *
58 * STANDARD DEFINES
59 *
60 **************************************************/
61
[295]62/* IPv6 */
63#if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETADDRINFO)
64
65#if defined(SH_COMPILE_STATIC) && defined(__linux__)
66#undef USE_IPVX
67#define SH_SOCKMAX 1
68#else
69
70#if defined(USE_IPV4)
71#undef USE_IPVX
72#else
73#define USE_IPVX 1
74#endif
75
76#define SH_SOCKMAX 8
77#endif
78
79#else
80#undef USE_IPVX
81#define SH_SOCKMAX 1
82#endif
83
84/* end IPv6 */
85
[283]86/* Standard buffer sizes.
87 * IPv6 is 8 groups of 4 hex digits seperated by colons.
[1]88 */
[295]89#define SH_IP_BUF 48
[1]90#define SH_MINIBUF 64
91#define SH_BUFSIZE 1024
92#define SH_MAXBUF 4096
93#define SH_PATHBUF 256
[170]94#define SH_MSG_BUF 64512
[1]95
[132]96#define SH_ERRBUF_SIZE 64
[131]97
[170]98/* MAX_PATH_STORE must be >= KEY_LEN
99 */
100#define MAX_PATH_STORE 12287
101
[1]102/* Sizes for arrays (user, group, timestamp).
103 */
[40]104#define SOCKPASS_MAX 14
[149]105#define USER_MAX 20
106#define GROUP_MAX 20
107#define TIM_MAX 32
[1]108
[149]109#define CMODE_SIZE 11
[40]110
[149]111#define ATTRBUF_SIZE 16
112#define ATTRBUF_USED 12
113
[1]114/* The number of bytes in a key,
115 * the number of chars in its hex repesentation,
116 * and the block size of the hash algorithm.
117 */
118#define KEY_BYT 24
119#define KEY_LEN 48
120#define KEY_BLOCK 24
[133]121#define KEYBUF_SIZE (KEY_LEN+1)
[1]122
123/* The length of the compiled-in password.
124 */
125#define PW_LEN 8
126
127#undef S_TRUE
128#define S_TRUE 1
129#undef S_FALSE
130#define S_FALSE 0
131
[481]132#undef GOOD
133#define GOOD S_TRUE
134#undef BAD
135#define BAD S_FALSE
136
[488]137#define SH_SILENT_FULL 2
138#define SH_SILENT_STD 1
[481]139
[488]140
[481]141#ifdef HAVE_INTTYPES_H
142#include <inttypes.h>
143#endif
144#ifdef HAVE_STDINT_H
145#include <stdint.h>
146#endif
147
148#if !defined(HAVE_UINT16_T)
149#define UINT16 unsigned short
150#else
151#define UINT16 uint16_t
152#endif
153
154#if !defined(HAVE_UINT32_T)
155
[1]156/* An unsigned integer guaranteed to be 32 bit.
157 */
158#if defined(HAVE_INT_32)
159#define UINT32 unsigned int
160#define SINT32 int
161#elif defined(HAVE_LONG_32)
162#define UINT32 unsigned long
163#define SINT32 long
164#elif defined(HAVE_SHORT_32)
165#define UINT32 unsigned short
166#define SINT32 short
[415]167#else
168#error "No 32 bit integer type found"
[1]169#endif
170
[481]171#else
172#define UINT32 uint32_t
173#define SINT32 int32_t
[1]174
[265]175#endif
176
[156]177#if !defined(HAVE_UINT64_T)
[1]178
179#ifdef HAVE_LONG_LONG_64
180#define UINT64 unsigned long long
181#else
182#ifdef HAVE_LONG_64
183#define UINT64 unsigned long
184#else
[156]185#error "no 64bit type found"
[1]186#endif
187#endif
188
189#else
190#define UINT64 uint64_t
191#endif
192
193
194
195#define UBYTE unsigned char
196
[444]197enum {
198 SH_TIGER192 = 0,
199 SH_SHA1 = 1,
200 SH_MD5 = 2,
201 SH_SHA256 = 3
202};
[1]203
[444]204
[1]205enum {
206 SH_CHECK_NONE = 0,
207 SH_CHECK_INIT = 1,
208 SH_CHECK_CHECK = 2
209};
210
[143]211#define SH_MOD_THREAD 1
212#define SH_MOD_ACTIVE 0
213#define SH_MOD_FAILED -1
[207]214#define SH_MOD_OFFSET 10
[156]215
[114]216/* Flags for file status
217 */
218#define SH_FFLAG_ALLIGNORE (1<<0)
219#define SH_FFLAG_VISITED (1<<1)
220#define SH_FFLAG_CHECKED (1<<3)
221#define SH_FFLAG_REPORTED (1<<3)
[115]222#define SH_FFLAG_SUIDCHK (1<<4)
[458]223#define SH_FFLAG_ENOENT (1<<5)
[93]224
[114]225#define SH_FFLAG_ALLIGNORE_SET(a) (((a) & SH_FFLAG_ALLIGNORE) != 0)
226#define SET_SH_FFLAG_ALLIGNORE(a) ((a) |= SH_FFLAG_ALLIGNORE)
227#define CLEAR_SH_FFLAG_ALLIGNORE(a) ((a) &= ~SH_FFLAG_ALLIGNORE)
228
229#define SH_FFLAG_VISITED_SET(a) (((a) & SH_FFLAG_VISITED) != 0)
230#define SET_SH_FFLAG_VISITED(a) ((a) |= SH_FFLAG_VISITED)
231#define CLEAR_SH_FFLAG_VISITED(a) ((a) &= ~SH_FFLAG_VISITED)
232
233#define SH_FFLAG_CHECKED_SET(a) (((a) & SH_FFLAG_VISITED) != 0)
234#define SET_SH_FFLAG_CHECKED(a) ((a) |= SH_FFLAG_VISITED)
235#define CLEAR_SH_FFLAG_CHECKED(a) ((a) &= ~SH_FFLAG_VISITED)
236
237#define SH_FFLAG_REPORTED_SET(a) (((a) & SH_FFLAG_REPORTED) != 0)
238#define SET_SH_FFLAG_REPORTED(a) ((a) |= SH_FFLAG_REPORTED)
239#define CLEAR_SH_FFLAG_REPORTED(a) ((a) &= ~SH_FFLAG_REPORTED)
240
[115]241#define SH_FFLAG_SUIDCHK_SET(a) (((a) & SH_FFLAG_SUIDCHK) != 0)
242#define SET_SH_FFLAG_SUIDCHK(a) ((a) |= SH_FFLAG_SUIDCHK)
243#define CLEAR_SH_FFLAG_SUIDCHK(a) ((a) &= ~SH_FFLAG_SUIDCHK)
[114]244
[458]245#define SH_FFLAG_ENOENT_SET(a) (((a) & SH_FFLAG_ENOENT) != 0)
246#define SET_SH_FFLAG_ENOENT(a) ((a) |= SH_FFLAG_ENOENT)
247#define CLEAR_SH_FFLAG_ENOENT(a) ((a) &= ~SH_FFLAG_ENOENT)
248
[367]249/* Flags for inotify
250 */
251#define SH_INOTIFY_USE (1<<0)
252#define SH_INOTIFY_DOSCAN (1<<1)
253#define SH_INOTIFY_NEEDINIT (1<<2)
[373]254#define SH_INOTIFY_INSCAN (1<<3)
[433]255#define SH_INOTIFY_IFUSED(a) if ((sh.flag.inotify & SH_INOTIFY_USE) != 0) { a }
[114]256
[367]257
[1]258/**************************************************
259 *
260 * TYPEDEFS
261 *
262 **************************************************/
263
264enum {
265 SH_LEVEL_READONLY = 1,
266 SH_LEVEL_LOGFILES = 2,
267 SH_LEVEL_LOGGROW = 3,
268 SH_LEVEL_NOIGNORE = 4,
269 SH_LEVEL_ALLIGNORE = 5,
270 SH_LEVEL_ATTRIBUTES = 6,
271 SH_LEVEL_USER0 = 7,
272 SH_LEVEL_USER1 = 8,
[27]273 SH_LEVEL_USER2 = 9,
274 SH_LEVEL_USER3 = 10,
275 SH_LEVEL_USER4 = 11,
276 SH_LEVEL_PRELINK = 12
[1]277};
278
279typedef struct {
280 time_t alarm_interval;
281 time_t alarm_last;
282} sh_timer_t;
283
284typedef struct {
285 char path[SH_PATHBUF];
286 char hash[KEY_LEN+1];
287} sh_sh_df;
288
289typedef struct {
290 char user[USER_MAX];
291 char group[GROUP_MAX];
292 char home[SH_PATHBUF];
293 uid_t uid;
294 gid_t gid;
295} sh_sh_user;
296
297typedef struct {
298 char name[SH_PATHBUF]; /* local hostname */
299 char system[SH_MINIBUF]; /* system */
300 char release[SH_MINIBUF]; /* release */
301 char machine[SH_MINIBUF]; /* machine */
302} sh_sh_local;
303
304typedef struct {
305 char name[SH_PATHBUF];
306 char alt[SH_PATHBUF];
307} sh_sh_remote;
308
309typedef struct {
310 unsigned long bytes_hashed; /* bytes last check */
311 unsigned long bytes_speed; /* bytes/sec last check */
312 unsigned long mail_success; /* mails sent */
313 unsigned long mail_failed; /* mails not sent */
314 time_t time_start; /* start last check */
315 time_t time_check; /* time last check */
316 unsigned long dirs_checked; /* #dirs last check */
317 unsigned long files_checked; /* #files last check */
[405]318 unsigned long files_report; /* #file reports */
319 unsigned long files_error; /* #file access error */
320 unsigned long files_nodir; /* #file not a directory*/
[1]321} sh_sh_stat;
322
323typedef struct {
324 int exit; /* exit value */
325 int checkSum; /* whether to init/check checksums */
326 int update; /* update db */
327 int opts; /* reading cl options */
[256]328 int started; /* finished with startup stuff */
[1]329 int isdaemon; /* daemon or not */
330 int loop; /* go in loop even if not daemon */
331 int nice; /* desired nicety */
332 int isserver; /* server or not */
333 int islocked; /* BAD if logfile not locked */
334 int smsg; /* GOOD if end message sent */
335 int log_start; /* TRUE if new audit trail */
336 int reportonce; /* TRUE if bad files only once rep.*/
337 int fulldetail; /* TRUE if full details requested */
338 int client_severity; /* TRUE if client severity used */
339 int client_class; /* TRUE if client class used */
[481]340 int hidefile; /* TRUE if file not shown in log */
341 int inotify; /* Flags for inotify */
[1]342 int audit;
343 unsigned long aud_mask;
344} sh_sh_flag;
345
346typedef struct {
347
348 char prg_name[8];
[162]349
350 UINT64 pid;
[1]351
352 sh_sh_df exec;
353 sh_sh_df conf;
354 sh_sh_df data;
355
356 sh_sh_user real;
357 sh_sh_user effective;
358 sh_sh_user run;
359
360 sh_sh_local host;
361
362 sh_sh_remote srvtime;
363 sh_sh_remote srvmail;
364 sh_sh_remote srvexport;
365 sh_sh_remote srvcons;
366 sh_sh_remote srvlog;
367
368 sh_sh_stat statistics;
369 sh_sh_flag flag;
370
371#ifdef SH_STEALTH
372 unsigned long off_data;
373#endif
374
375 sh_timer_t mailNum;
376 sh_timer_t mailTime;
377 sh_timer_t fileCheck;
378
379 int looptime; /* timing for main loop */
380 /*@null@*//*@out@*/ char * timezone;
[411]381
[481]382 int delayload;
383
[411]384#ifdef SCREW_IT_UP
385 int sigtrap_max_duration;
386#endif
387
[481]388 char * outpath;
[1]389} sh_struct;
390
391
392extern volatile int sig_raised;
393extern volatile int sig_urgent;
394extern volatile int sig_debug_switch; /* SIGUSR1 */
395extern volatile int sig_suspend_switch; /* SIGUSR2 */
[143]396extern volatile int sh_global_suspend_flag;
[1]397extern volatile int sig_fresh_trail; /* SIGIOT */
[143]398extern volatile int sh_thread_pause_flag;
[1]399extern volatile int sig_config_read_again; /* SIGHUP */
400extern volatile int sig_terminate; /* SIGQUIT */
401extern volatile int sig_termfast; /* SIGTERM */
402extern volatile int sig_force_check; /* SIGTTOU */
[488]403extern volatile int sig_force_silent; /* SIGTSTP */
404extern volatile int sh_global_check_silent;
[481]405extern volatile int sh_load_delta_flag;
[1]406
407extern long int eintr__result;
408
[20]409extern int sh_argc_store;
410extern char ** sh_argv_store;
411
[1]412#include "sh_calls.h"
413
414
415typedef struct {
[40]416 char sh_sockpass[2*SOCKPASS_MAX+2];
[1]417 char sigkey_old[KEY_LEN+1];
418 char sigkey_new[KEY_LEN+1];
419 char mailkey_old[KEY_LEN+1];
420 char mailkey_new[KEY_LEN+1];
421 char crypt[KEY_LEN+1];
422 char session[KEY_LEN+1];
423 char vernam[KEY_LEN+1];
424 int mlock_failed;
425
426 char pw[PW_LEN];
427
428 char poolv[KEY_BYT];
429 int poolc;
430
431 int rngI;
432 UINT32 rng0[3];
433 UINT32 rng1[3];
434 UINT32 rng2[3];
435
[156]436 UINT32 res_vec[6];
437
[1]438 UINT32 ErrFlag[2];
439
440#ifdef SH_ENCRYPT
441 /*@out@*/ keyInstance keyInstE;
442 /*@out@*/ keyInstance keyInstD;
443#endif
444} sh_key_t;
445
446extern sh_struct sh;
447/*@null@*/ extern sh_key_t *skey;
448
[22]449/**************************************************
450 *
451 * macros
452 *
453 **************************************************/
[1]454
[459]455#if defined(SH_ABORT_ON_ERROR)
456#define SH_ABORT abort()
457#else
458#define SH_ABORT
459#endif
460
[76]461
[149]462
[76]463/* The semantics of the built-in are that it is expected that expr == const
464 * for __builtin_expect ((expr), const)
465 */
466#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
467#define SH_LIKELY(expr) (__builtin_expect((expr), 1))
468#define SH_UNLIKELY(expr) (__builtin_expect((expr), 0))
469#else
470#define SH_LIKELY(expr) (expr)
471#define SH_UNLIKELY(expr) (expr)
472#endif
473
[22]474/* signal-safe log function
475 */
[170]476int safe_logger (int thesignal, int method, char * details);
477void safe_fatal (const char * details, const char *f, int l);
[22]478
[25]479#define SH_VALIDATE_EQ(a,b) \
[22]480 do { \
[34]481 if ((a) != (b)) safe_fatal(#a " != " #b, FIL__, __LINE__);\
[22]482 } while (0)
483
[25]484#define SH_VALIDATE_NE(a,b) \
485 do { \
[34]486 if ((a) == (b)) safe_fatal(#a " == " #b, FIL__, __LINE__);\
[25]487 } while (0)
[22]488
[68]489#define SH_VALIDATE_GE(a,b) \
490 do { \
491 if ((a) < (b)) safe_fatal(#a " < " #b, FIL__, __LINE__);\
492 } while (0)
493
[1]494#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
[412]495#ifdef USE_SUID
[1]496#define MLOCK(a, b) \
[481]497 if ((skey != NULL) && skey->mlock_failed == S_FALSE){ \
[1]498 (void) sl_set_suid(); \
[481]499 if (sh_unix_mlock(FIL__, __LINE__, a, b) < 0) skey->mlock_failed = S_TRUE; \
[412]500 (void) sl_unset_suid(); }
[1]501#else
502#define MLOCK(a, b) \
[481]503 if ((skey != NULL) && skey->mlock_failed == S_FALSE){ \
504 if (sh_unix_mlock(FIL__, __LINE__, a, b) < 0) skey->mlock_failed = S_TRUE; }
[412]505#endif
506#else
507#define MLOCK(a, b) \
[1]508 ;
509#endif
510
511#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
[412]512#ifdef USE_SUID
[1]513#define MUNLOCK(a, b) \
[481]514 if ((skey != NULL) && skey->mlock_failed == S_FALSE){ \
[1]515 (void) sl_set_suid(); \
516 (void) sh_unix_munlock( a, b );\
[412]517 (void) sl_unset_suid(); }
[1]518#else
519#define MUNLOCK(a, b) \
[481]520 if ((skey != NULL) && skey->mlock_failed == S_FALSE){ \
[412]521 (void) sh_unix_munlock( a, b ); }
522#endif
523#else
524#define MUNLOCK(a, b) \
[1]525 ;
526#endif
527
528#ifdef SH_STEALTH
529void sh_do_encode (char * str, int len);
530#define sh_do_decode sh_do_encode
531#endif
532
533/* #if defined(SCREW_IT_UP)
534 * extern volatile int sh_not_traced;
535 * inline int sh_sigtrap_prepare();
536 * inline int sh_derr();
537 * #endif
538 */
539
540#if defined(SCREW_IT_UP) && (defined(__FreeBSD__) || defined(__linux__)) && defined(__i386__)
541#define BREAKEXIT(expr) \
542 do { \
543 int ixi; \
544 for (ixi = 0; ixi < 8; ++ixi) { \
545 if ((*(volatile unsigned *)((unsigned) expr + ixi) & 0xff) == 0xcc) \
546 _exit(EXIT_FAILURE); \
547 } \
548 } \
549 while (1 == 0)
550#else
551#define BREAKEXIT(expr)
552#endif
553
554
555
556#include "sh_cat.h"
557#include "sh_trace.h"
558#include "sh_mem.h"
559
560#endif
561
562/* CRIT: */
563/* NEW_CLIENT <client> */
564/* BAD_CLIENT <client> -- <details> */
565/* ERR_CLIENT <client> -- <details> */
566
567/* ALERT: */
568/* LOG_KEY samhain|yule <key> */
569/* STARTUP samhain|yule -- user <username> */
570/* EXIT samhain|yule */
571/* GOODSIG <file> <user> */
572/* FP_KEY <fingerprint> */
573/* GOODSIG_DAT <file> <user> */
574/* FP_KEY_DAT <fingerprint> */
575/* TIGER_CFG <file> <checksum> */
576/* TIGER_DAT <file> <checksum> */
577
578/* PANIC -- <details> */
579/* ERROR -- <details> */
580
581/* Policy */
582/* POLICY <code> <file> */
583/* <code> = MISSING || ADDED || NOT_A_DIRECTORY || <policy> */
584
585
586
Note: See TracBrowser for help on using the repository browser.