new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / rootcheck.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
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
7  * Foundation
8  */
9
10 /*
11  * Rootcheck
12  * Copyright (C) 2003 Daniel B. Cid <daniel@underlinux.com.br>
13  * http://www.ossec.net/rootcheck/
14  */
15
16 #include "headers/shared.h"
17 #include "rootcheck.h"
18
19 rkconfig rootcheck;
20 char **rk_sys_file;
21 char **rk_sys_name;
22 int rk_sys_count;
23 char total_ports_udp[65535 + 1];
24 char total_ports_tcp[65535 + 1];
25
26 #ifndef ARGV0
27 #define ARGV0 "rootcheck"
28 #endif
29
30 #ifndef OSSECHIDS
31
32
33 /* Print help statement */
34 void help_rootcheck()
35 {
36     print_header();
37     print_out("  %s: -[Vhdtsr] [-c config] [-D dir]", ARGV0);
38     print_out("    -V          Version and license message");
39     print_out("    -h          Print this help message");
40     print_out("    -d          Execute in debug mode. This parameter");
41     print_out("                can be specified multiple times");
42     print_out("                to increase the debug level.");
43     print_out("    -t          Test configuration");
44     print_out("    -s          Scan the whole system");
45     print_out("    -r          Read all the files for kernel-based detection");
46     print_out("    -c <config> Configuration file to use");
47     print_out("    -D <dir>    Directory to chroot into (default: %s)", DEFAULTDIR);
48     print_out(" ");
49     exit(1);
50 }
51
52 int main(int argc, char **argv)
53 {
54     int test_config = 0;
55     const char *cfg = "./rootcheck.conf";
56
57 #else
58
59 int rootcheck_init(int test_config)
60 {
61     const char *cfg = DEFAULTCPATH;
62
63 #endif /* OSSECHIDS */
64
65     int c;
66
67     /* Zero the structure, initialize default values */
68     rootcheck.workdir = NULL;
69     rootcheck.basedir = NULL;
70     rootcheck.unixaudit = NULL;
71     rootcheck.ignore = NULL;
72     rootcheck.rootkit_files = NULL;
73     rootcheck.rootkit_trojans = NULL;
74     rootcheck.winaudit = NULL;
75     rootcheck.winmalware = NULL;
76     rootcheck.winapps = NULL;
77     rootcheck.daemon = 1;
78     rootcheck.notify = QUEUE;
79     rootcheck.scanall = 0;
80     rootcheck.readall = 0;
81     rootcheck.disabled = 0;
82     rootcheck.skip_nfs = 0;
83     rootcheck.alert_msg = NULL;
84     rootcheck.time = ROOTCHECK_WAIT;
85
86     rootcheck.checks.rc_dev = 1;
87     rootcheck.checks.rc_files = 1;
88     rootcheck.checks.rc_if = 1;
89     rootcheck.checks.rc_pids = 1;
90     rootcheck.checks.rc_ports = 1;
91     rootcheck.checks.rc_sys = 1;
92     rootcheck.checks.rc_trojans = 1;
93
94 #ifdef OSSECHIDS
95     rootcheck.tsleep = (unsigned int) getDefine_Int("rootcheck", "sleep", 0, 64);
96 #endif
97
98 #ifdef WIN32
99     rootcheck.checks.rc_winaudit = 1;
100     rootcheck.checks.rc_winmalware = 1;
101     rootcheck.checks.rc_winapps = 1;
102 #else
103     rootcheck.checks.rc_unixaudit = 1;
104 #endif
105
106     /* We store up to 255 alerts in there */
107     os_calloc(256, sizeof(char *), rootcheck.alert_msg);
108     c = 0;
109     while (c <= 255) {
110         rootcheck.alert_msg[c] = NULL;
111         c++;
112     }
113
114 #ifndef OSSECHIDS
115     rootcheck.notify = SYSLOG;
116     rootcheck.daemon = 0;
117     while ((c = getopt(argc, argv, "VstrdhD:c:")) != -1) {
118         switch (c) {
119             case 'V':
120                 print_version();
121                 break;
122             case 'h':
123                 help_rootcheck();
124                 break;
125             case 'd':
126                 nowDebug();
127                 break;
128             case 'D':
129                 if (!optarg) {
130                     ErrorExit("%s: -D needs an argument", ARGV0);
131                 }
132                 rootcheck.workdir = optarg;
133                 break;
134             case 'c':
135                 if (!optarg) {
136                     ErrorExit("%s: -c needs an argument", ARGV0);
137                 }
138                 cfg = optarg;
139                 break;
140             case 's':
141                 rootcheck.scanall = 1;
142                 break;
143             case 't':
144                 test_config = 1;
145                 break;
146             case 'r':
147                 rootcheck.readall = 1;
148                 break;
149             default:
150                 help_rootcheck();
151                 break;
152         }
153     }
154 #ifdef WIN32
155     /* Start Winsock */
156     {
157         WSADATA wsaData;
158         if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
159             ErrorExit("%s: WSAStartup() failed", ARGV0);
160         }
161     }
162 #endif /* WIN32 */
163
164 #endif /* OSSECHIDS */
165
166     /* Start up message */
167     debug1(STARTED_MSG, ARGV0);
168
169     /* Check if the configuration is present */
170     if (File_DateofChange(cfg) < 0) {
171         merror("%s: Configuration file '%s' not found", ARGV0, cfg);
172         return (-1);
173     }
174
175     /* Read configuration  --function specified twice (check makefile) */
176     if (Read_Rootcheck_Config(cfg) < 0) {
177         ErrorExit(CONFIG_ERROR, ARGV0, cfg);
178     }
179
180     /* If testing config, exit here */
181     if (test_config) {
182         return (0);
183     }
184
185     /* Return 1 disables rootcheck */
186     if (rootcheck.disabled == 1) {
187         verbose("%s: Rootcheck disabled. Exiting.", ARGV0);
188         return (1);
189     }
190
191     /* Check if Unix audit file is configured */
192     if (!rootcheck.unixaudit) {
193 #ifndef WIN32
194         log2file("%s: System audit file not configured.", ARGV0);
195 #endif
196     }
197
198     /* Set default values */
199     if (rootcheck.workdir == NULL) {
200         rootcheck.workdir = DEFAULTDIR;
201     }
202
203 #ifdef OSSECHIDS
204     /* Start up message */
205 #ifdef WIN32
206     verbose(STARTUP_MSG, "ossec-rootcheck", getpid());
207 #else
208
209     /* Connect to the queue if configured to do so */
210     if (rootcheck.notify == QUEUE) {
211         debug1("%s: Starting queue ...", ARGV0);
212
213         /* Start the queue */
214         if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
215             merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno));
216
217             /* 5 seconds to see if the agent starts */
218             sleep(5);
219             if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
220                 /* Wait 10 more seconds */
221                 merror(QUEUE_ERROR, ARGV0, DEFAULTQPATH, strerror(errno));
222                 sleep(10);
223                 if ((rootcheck.queue = StartMQ(DEFAULTQPATH, WRITE)) < 0) {
224                     ErrorExit(QUEUE_FATAL, ARGV0, DEFAULTQPATH);
225                 }
226             }
227         }
228     }
229
230 #endif /* WIN32 */
231
232 #endif /* OSSECHIDS */
233
234     /* Initialize rk list */
235     rk_sys_name = (char **) calloc(MAX_RK_SYS + 2, sizeof(char *));
236     rk_sys_file = (char **) calloc(MAX_RK_SYS + 2, sizeof(char *));
237     if (!rk_sys_name || !rk_sys_file) {
238         ErrorExit(MEM_ERROR, ARGV0, errno, strerror(errno));
239     }
240     rk_sys_name[0] = NULL;
241     rk_sys_file[0] = NULL;
242
243 #ifndef OSSECHIDS
244 #ifndef WIN32
245     /* Start signal handling */
246     StartSIG(ARGV0);
247 #endif
248     debug1("%s: DEBUG: Running run_rk_check", ARGV0);
249     run_rk_check();
250
251     debug1("%s: DEBUG: Leaving...", ARGV0);
252 #endif /* OSSECHIDS */
253     return (0);
254 }
255