source: trunk/include/samhain.h@ 470

Last change on this file since 470 was 459, checked in by katerina, 10 years ago

Fix for ticket #360 (free on null pointer).

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