novi upstream verzije 2.8.3
[ossec-hids.git] / src / syscheckd / syscheck.c
1 /* @(#) $Id: ./src/syscheckd/syscheck.c, 2011/09/08 dcid Exp $
2  */
3
4 /* Copyright (C) 2009 Trend Micro Inc.
5  * All rights reserved.
6  *
7  * This program is a free software; you can redistribute it
8  * and/or modify it under the terms of the GNU General Public
9  * License (version 2) as published by the FSF - Free Software
10  * Foundation.
11  *
12  * License details at the LICENSE file included with OSSEC or
13  * online at: http://www.ossec.net/en/licensing.html
14  */
15
16
17 /*
18  * Syscheck v 0.3
19  * Copyright (C) 2003 Daniel B. Cid <daniel@underlinux.com.br>
20  * http://www.ossec.net
21  *
22  * syscheck.c, 2004/03/17, Daniel B. Cid
23  */
24
25 /* Inclusion of syscheck into OSSEC */
26
27
28 #include "shared.h"
29 #include "syscheck.h"
30
31 #include "rootcheck/rootcheck.h"
32
33 int dump_syscheck_entry(syscheck_config *syscheck, char *entry, int vals, int reg, char *restrictfile);
34
35 #ifdef USE_MAGIC
36 #include <magic.h>
37 magic_t magic_cookie = 0;
38
39 void init_magic(magic_t* cookie_ptr)
40 {
41     if(!cookie_ptr || *cookie_ptr) return;
42
43     *cookie_ptr = magic_open(MAGIC_MIME_TYPE);
44
45     if(!*cookie_ptr)
46     {
47         const char* err = magic_error(*cookie_ptr);
48         merror("%s: ERROR: Can't init libmagic: %s", ARGV0, err ? err : "unknown");
49     }
50     else if(magic_load(*cookie_ptr, NULL) < 0)
51     {
52         const char* err = magic_error(*cookie_ptr);
53         merror("%s: ERROR: Can't load magic file: %s", ARGV0, err ? err : "unknown");
54         magic_close(*cookie_ptr);
55         *cookie_ptr = 0;
56     }
57 }
58 #endif
59
60
61 /* void read_internal()
62  * Reads syscheck internal options.
63  */
64 void read_internal(int debug_level)
65 {
66     syscheck.tsleep = getDefine_Int("syscheck","sleep",0,64);
67     syscheck.sleep_after = getDefine_Int("syscheck","sleep_after",1,9999);
68
69     /* Check current debug_level
70      * Command line setting takes precedence
71      */
72     if (debug_level == 0)
73     {
74         /* Getting debug level */
75         debug_level = getDefine_Int("syscheck", "debug", 0, 2);
76         while(debug_level != 0)
77         {
78             nowDebug();
79             debug_level--;
80         }
81     }
82
83     return;
84 }
85
86
87 #ifdef WIN32
88 /* int Start_win32_Syscheck()
89  * syscheck main for windows
90  */
91 int Start_win32_Syscheck()
92 {
93     int debug_level = 0;
94     int r = 0;
95     char *cfg = DEFAULTCPATH;
96
97
98     /* Reading internal options */
99     read_internal(debug_level);
100
101
102     debug1(STARTED_MSG, ARGV0);
103
104
105     /* Zeroing the structure */
106     syscheck.workdir = DEFAULTDIR;
107
108
109     /* Checking if the configuration is present */
110     if(File_DateofChange(cfg) < 0)
111         ErrorExit(NO_CONFIG, ARGV0, cfg);
112
113
114     /* Read syscheck config */
115     if((r = Read_Syscheck_Config(cfg)) < 0)
116     {
117         ErrorExit(CONFIG_ERROR, ARGV0, cfg);
118     }
119     /* Disabled */
120     else if((r == 1) || (syscheck.disabled == 1))
121     {
122         if(!syscheck.dir)
123         {
124             merror(SK_NO_DIR, ARGV0);
125             dump_syscheck_entry(&syscheck, "", 0, 0, NULL);
126         }
127         else if(!syscheck.dir[0])
128         {
129             merror(SK_NO_DIR, ARGV0);
130         }
131         syscheck.dir[0] = NULL;
132
133         if(!syscheck.registry)
134         {
135             dump_syscheck_entry(&syscheck, "", 0, 1, NULL);
136         }
137         syscheck.registry[0] = NULL;
138
139         merror("%s: WARN: Syscheck disabled.", ARGV0);
140     }
141
142
143     /* Rootcheck config */
144     if(rootcheck_init(0) == 0)
145     {
146         syscheck.rootcheck = 1;
147     }
148     else
149     {
150         syscheck.rootcheck = 0;
151         merror("%s: WARN: Rootcheck module disabled.", ARGV0);
152     }
153
154
155
156     /* Printing options */
157     r = 0;
158     while(syscheck.registry[r] != NULL)
159     {
160         verbose("%s: INFO: Monitoring registry entry: '%s'.",
161                 ARGV0, syscheck.registry[r]);
162         r++;
163     }
164
165     r = 0;
166     while(syscheck.dir[r] != NULL)
167     {
168         verbose("%s: INFO: Monitoring directory: '%s'.",
169                 ARGV0, syscheck.dir[r]);
170         r++;
171     }
172
173
174     /* Start up message */
175     verbose(STARTUP_MSG, ARGV0, getpid());
176
177
178
179     /* Some sync time */
180     sleep(syscheck.tsleep + 10);
181
182
183     /* Waiting if agent started properly. */
184     os_wait();
185
186
187     start_daemon();
188
189
190     exit(0);
191 }
192 #endif
193
194
195
196 /* Syscheck unix main.
197  */
198 #ifndef WIN32
199 int main(int argc, char **argv)
200 {
201     int c,r;
202     int debug_level = 0;
203     int test_config = 0,run_foreground = 0;
204
205     char *cfg = DEFAULTCPATH;
206
207
208     /* Zeroing the structure */
209     syscheck.workdir = NULL;
210
211
212     /* Setting the name */
213     OS_SetName(ARGV0);
214
215
216     while((c = getopt(argc, argv, "VtdhfD:c:")) != -1)
217     {
218         switch(c)
219         {
220             case 'V':
221                 print_version();
222                 break;
223             case 'h':
224                 help(ARGV0);
225                 break;
226             case 'd':
227                 nowDebug();
228                 debug_level = 1;
229                 break;
230             case 'f':
231                 run_foreground = 1;
232                 break;
233             case 'D':
234                 if(!optarg)
235                     ErrorExit("%s: -D needs an argument",ARGV0);
236                 syscheck.workdir = optarg;
237                 break;
238             case 'c':
239                 if(!optarg)
240                     ErrorExit("%s: -c needs an argument",ARGV0);
241                 cfg = optarg;
242                 break;
243             case 't':
244                 test_config = 1;
245                 break;
246             default:
247                 help(ARGV0);
248                 break;
249         }
250     }
251
252
253     /* Reading internal options */
254     read_internal(debug_level);
255
256
257     debug1(STARTED_MSG, ARGV0);
258
259
260     /* Checking if the configuration is present */
261     if(File_DateofChange(cfg) < 0)
262         ErrorExit(NO_CONFIG, ARGV0, cfg);
263
264
265     /* Read syscheck config */
266     if((r = Read_Syscheck_Config(cfg)) < 0)
267     {
268         ErrorExit(CONFIG_ERROR, ARGV0, cfg);
269     }
270     else if((r == 1) || (syscheck.disabled == 1))
271     {
272         if(!syscheck.dir)
273         {
274             if(!test_config)
275                 merror(SK_NO_DIR, ARGV0);
276             dump_syscheck_entry(&syscheck, "", 0, 0, NULL);
277         }
278         else if(!syscheck.dir[0])
279         {
280             if(!test_config)
281                 merror(SK_NO_DIR, ARGV0);
282         }
283         syscheck.dir[0] = NULL;
284         if(!test_config)
285         {
286             merror("%s: WARN: Syscheck disabled.", ARGV0);
287         }
288     }
289
290
291     /* Rootcheck config */
292     if(rootcheck_init(test_config) == 0)
293     {
294         syscheck.rootcheck = 1;
295     }
296     else
297     {
298         syscheck.rootcheck = 0;
299         merror("%s: WARN: Rootcheck module disabled.", ARGV0);
300     }
301
302
303     /* Exit if testing config */
304     if(test_config)
305         exit(0);
306
307
308     /* Setting default values */
309     if(syscheck.workdir == NULL)
310         syscheck.workdir = DEFAULTDIR;
311
312
313     /* Setup libmagic */
314     #ifdef USE_MAGIC
315     init_magic(&magic_cookie);
316     #endif
317
318
319     if(!run_foreground)
320     {
321         nowDaemon();
322         goDaemon();
323     }
324
325     /* Initial time to settle */
326     sleep(syscheck.tsleep + 2);
327
328
329     /* Connect to the queue  */
330     if((syscheck.queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
331     {
332         merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno));
333
334         sleep(5);
335         if((syscheck.queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
336         {
337             /* more 10 seconds of wait.. */
338             merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno));
339             sleep(10);
340             if((syscheck.queue = StartMQ(DEFAULTQPATH,WRITE)) < 0)
341                 ErrorExit(QUEUE_FATAL,ARGV0,DEFAULTQPATH);
342         }
343     }
344
345
346     /* Start the signal handling */
347     StartSIG(ARGV0);
348
349
350     /* Creating pid */
351     if(CreatePID(ARGV0, getpid()) < 0)
352         merror(PID_ERROR,ARGV0);
353
354
355     /* Start up message */
356     verbose(STARTUP_MSG, ARGV0, (int)getpid());
357
358     if(syscheck.rootcheck)
359     {
360         verbose(STARTUP_MSG, "ossec-rootcheck", (int)getpid());
361     }
362
363
364     /* Printing directories to be monitored. */
365     r = 0;
366     while(syscheck.dir[r] != NULL)
367     {
368         verbose("%s: INFO: Monitoring directory: '%s'.",
369                 ARGV0, syscheck.dir[r]);
370         r++;
371     }
372
373     /* Checking directories set for real time. */
374     r = 0;
375     while(syscheck.dir[r] != NULL)
376     {
377         if(syscheck.opts[r] & CHECK_REALTIME)
378         {
379             #ifdef USEINOTIFY
380             verbose("%s: INFO: Directory set for real time monitoring: "
381                     "'%s'.", ARGV0, syscheck.dir[r]);
382             #elif WIN32
383             verbose("%s: INFO: Directory set for real time monitoring: "
384                     "'%s'.", ARGV0, syscheck.dir[r]);
385             #else
386             verbose("%s: WARN: Ignoring flag for real time monitoring on "
387                     "directory: '%s'.", ARGV0, syscheck.dir[r]);
388             #endif
389         }
390         r++;
391     }
392
393
394     /* Some sync time */
395     sleep(syscheck.tsleep + 10);
396
397
398     /* Start the daemon */
399     start_daemon();
400
401     return(0);
402 }
403 #endif /* ifndef WIN32 */
404
405
406 /* EOF */