1 /* Copyright (C) 2009 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
11 * Copyright (C) 2003 Daniel B. Cid <daniel@underlinux.com.br>
16 #include "rootcheck/rootcheck.h"
19 static void read_internal(int debug_level);
21 static void help_syscheckd(void) __attribute__((noreturn));
24 syscheck_config syscheck;
28 magic_t magic_cookie = 0;
31 void init_magic(magic_t *cookie_ptr)
33 if (!cookie_ptr || *cookie_ptr) {
37 *cookie_ptr = magic_open(MAGIC_MIME_TYPE);
40 const char *err = magic_error(*cookie_ptr);
41 merror("%s: ERROR: Can't init libmagic: %s", ARGV0, err ? err : "unknown");
42 } else if (magic_load(*cookie_ptr, NULL) < 0) {
43 const char *err = magic_error(*cookie_ptr);
44 merror("%s: ERROR: Can't load magic file: %s", ARGV0, err ? err : "unknown");
45 magic_close(*cookie_ptr);
49 #endif /* USE_MAGIC */
51 /* Read syscheck internal options */
52 static void read_internal(int debug_level)
54 syscheck.tsleep = (unsigned int) getDefine_Int("syscheck", "sleep", 0, 64);
55 syscheck.sleep_after = getDefine_Int("syscheck", "sleep_after", 1, 9999);
57 /* Check current debug_level
58 * Command line setting takes precedence
60 if (debug_level == 0) {
61 debug_level = getDefine_Int("syscheck", "debug", 0, 2);
62 while (debug_level != 0) {
72 /* syscheck main for Windows */
73 int Start_win32_Syscheck()
77 char *cfg = DEFAULTCPATH;
79 /* Read internal options */
80 read_internal(debug_level);
82 debug1(STARTED_MSG, ARGV0);
84 /* Check if the configuration is present */
85 if (File_DateofChange(cfg) < 0) {
86 ErrorExit(NO_CONFIG, ARGV0, cfg);
89 /* Read syscheck config */
90 if ((r = Read_Syscheck_Config(cfg)) < 0) {
91 ErrorExit(CONFIG_ERROR, ARGV0, cfg);
92 } else if ((r == 1) || (syscheck.disabled == 1)) {
95 merror(SK_NO_DIR, ARGV0);
96 dump_syscheck_entry(&syscheck, "", 0, 0, NULL);
97 } else if (!syscheck.dir[0]) {
98 merror(SK_NO_DIR, ARGV0);
100 syscheck.dir[0] = NULL;
102 if (!syscheck.registry) {
103 dump_syscheck_entry(&syscheck, "", 0, 1, NULL);
105 syscheck.registry[0] = NULL;
107 merror("%s: WARN: Syscheck disabled.", ARGV0);
110 /* Rootcheck config */
111 if (rootcheck_init(0) == 0) {
112 syscheck.rootcheck = 1;
114 syscheck.rootcheck = 0;
115 merror("%s: WARN: Rootcheck module disabled.", ARGV0);
120 while (syscheck.registry[r] != NULL) {
121 verbose("%s: INFO: Monitoring registry entry: '%s'.",
122 ARGV0, syscheck.registry[r]);
126 /* Print directories to be monitored */
128 while (syscheck.dir[r] != NULL) {
130 verbose("%s: INFO: Monitoring directory: '%s', with options %s.",
131 ARGV0, syscheck.dir[r],
132 syscheck_opts2str(optstr, sizeof( optstr ), syscheck.opts[r]));
138 for (r = 0; syscheck.ignore[r] != NULL; r++)
139 verbose("%s: INFO: ignoring: '%s'",
140 ARGV0, syscheck.ignore[r]);
143 /* Print files with no diff. */
144 if (syscheck.nodiff){
146 while (syscheck.nodiff[r] != NULL) {
147 verbose("%s: INFO: No diff for file: '%s'",
148 ARGV0, syscheck.nodiff[r]);
153 /* Start up message */
154 verbose(STARTUP_MSG, ARGV0, getpid());
157 sleep(syscheck.tsleep + 10);
159 /* Wait if agent started properly */
169 /* Print help statement */
170 static void help_syscheckd()
173 print_out(" %s: -[Vhdtf] [-c config]", ARGV0);
174 print_out(" -V Version and license message");
175 print_out(" -h This help message");
176 print_out(" -d Execute in debug mode. This parameter");
177 print_out(" can be specified multiple times");
178 print_out(" to increase the debug level.");
179 print_out(" -t Test configuration");
180 print_out(" -f Run in foreground");
181 print_out(" -c <config> Configuration file to use (default: %s)", DEFAULTCPATH);
186 /* Syscheck unix main */
187 int main(int argc, char **argv)
191 int test_config = 0, run_foreground = 0;
192 const char *cfg = DEFAULTCPATH;
197 while ((c = getopt(argc, argv, "Vtdhfc:")) != -1) {
214 ErrorExit("%s: -c needs an argument", ARGV0);
227 /* Read internal options */
228 read_internal(debug_level);
230 debug1(STARTED_MSG, ARGV0);
232 /* Check if the configuration is present */
233 if (File_DateofChange(cfg) < 0) {
234 ErrorExit(NO_CONFIG, ARGV0, cfg);
237 /* Read syscheck config */
238 if ((r = Read_Syscheck_Config(cfg)) < 0) {
239 ErrorExit(CONFIG_ERROR, ARGV0, cfg);
240 } else if ((r == 1) || (syscheck.disabled == 1)) {
243 merror(SK_NO_DIR, ARGV0);
245 dump_syscheck_entry(&syscheck, "", 0, 0, NULL);
246 } else if (!syscheck.dir[0]) {
248 merror(SK_NO_DIR, ARGV0);
251 syscheck.dir[0] = NULL;
253 merror("%s: WARN: Syscheck disabled.", ARGV0);
257 /* Rootcheck config */
258 if (rootcheck_init(test_config) == 0) {
259 syscheck.rootcheck = 1;
261 syscheck.rootcheck = 0;
262 merror("%s: WARN: Rootcheck module disabled.", ARGV0);
265 /* Exit if testing config */
272 init_magic(&magic_cookie);
275 if (!run_foreground) {
280 /* Initial time to settle */
281 sleep(syscheck.tsleep + 2);
283 /* Connect to the queue */
284 if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
285 merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno));
288 if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
289 /* more 10 seconds of wait */
290 merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno));
292 if ((syscheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
293 ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
298 /* Start signal handling */
302 if (CreatePID(ARGV0, getpid()) < 0) {
303 merror(PID_ERROR, ARGV0);
306 /* Start up message */
307 verbose(STARTUP_MSG, ARGV0, (int)getpid());
309 if (syscheck.rootcheck) {
310 verbose(STARTUP_MSG, "ossec-rootcheck", (int)getpid());
313 /* Print directories to be monitored */
315 while (syscheck.dir[r] != NULL) {
317 verbose("%s: INFO: Monitoring directory: '%s', with options %s.",
318 ARGV0, syscheck.dir[r],
319 syscheck_opts2str(optstr, sizeof( optstr ), syscheck.opts[r]));
325 for (r = 0; syscheck.ignore[r] != NULL; r++)
326 verbose("%s: INFO: ignoring: '%s'",
327 ARGV0, syscheck.ignore[r]);
329 /* Print files with no diff. */
330 if (syscheck.nodiff){
332 while (syscheck.nodiff[r] != NULL) {
333 verbose("%s: INFO: No diff for file: '%s'",
334 ARGV0, syscheck.nodiff[r]);
339 /* Check directories set for real time */
341 while (syscheck.dir[r] != NULL) {
342 if (syscheck.opts[r] & CHECK_REALTIME) {
343 #ifdef INOTIFY_ENABLED
344 verbose("%s: INFO: Directory set for real time monitoring: "
345 "'%s'.", ARGV0, syscheck.dir[r]);
347 verbose("%s: INFO: Directory set for real time monitoring: "
348 "'%s'.", ARGV0, syscheck.dir[r]);
350 verbose("%s: WARN: Ignoring flag for real time monitoring on "
351 "directory: '%s'.", ARGV0, syscheck.dir[r]);
358 sleep(syscheck.tsleep + 10);
360 /* Start the daemon */