new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / check_rc_files.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 #include "shared.h"
11 #include "rootcheck.h"
12
13
14 /* Read the file pointer specified (rootkit_files)
15  * and check if the configured file is there
16  */
17 void check_rc_files(const char *basedir, FILE *fp)
18 {
19     char buf[OS_SIZE_1024 + 1];
20     char file_path[OS_SIZE_1024 + 1];
21
22     char *file;
23     char *name;
24     char *link;
25
26     int _errors = 0;
27     int _total = 0;
28
29     debug1("%s: DEBUG: Starting on check_rc_files", ARGV0);
30
31     while (fgets(buf, OS_SIZE_1024, fp) != NULL) {
32         char *nbuf;
33
34         /* Remove newline at the end */
35         nbuf = strchr(buf, '\n');
36         if (nbuf) {
37             *nbuf = '\0';
38         }
39
40         /* Assign buf to be used */
41         nbuf = buf;
42
43         /* Skip comments and blank lines */
44         while (*nbuf != '\0') {
45             if (*nbuf == ' ' || *nbuf == '\t') {
46                 nbuf++;
47                 continue;
48             } else if (*nbuf == '#') {
49                 goto newline;
50             } else {
51                 break;
52             }
53         }
54
55         if (*nbuf == '\0') {
56             goto newline;
57         }
58
59         /* File now may be valid */
60         file = nbuf;
61         name = nbuf;
62
63         /* Get the file and the rootkit name */
64         while (*nbuf != '\0') {
65             if (*nbuf == ' ' || *nbuf == '\t') {
66                 /* Set the limit for the file */
67                 *nbuf = '\0';
68                 nbuf++;
69                 break;
70             } else {
71                 nbuf++;
72             }
73         }
74
75         if (*nbuf == '\0') {
76             goto newline;
77         }
78
79         /* Some ugly code to remove spaces and \t */
80         while (*nbuf != '\0') {
81             if (*nbuf == '!') {
82                 nbuf++;
83                 if (*nbuf == ' ' || *nbuf == '\t') {
84                     nbuf++;
85                     name = nbuf;
86
87                     break;
88                 }
89             } else if (*nbuf == ' ' || *nbuf == '\t') {
90                 nbuf++;
91                 continue;
92             } else {
93                 goto newline;
94             }
95         }
96
97         /* Get the link (if present) */
98         link = strchr(nbuf, ':');
99         if (link) {
100             *link = '\0';
101
102             link++;
103             if (*link == ':') {
104                 link++;
105             }
106         }
107
108         /* Clean any space or tab at the end */
109         nbuf = strchr(nbuf, ' ');
110         if (nbuf) {
111             *nbuf = '\0';
112
113             nbuf = strchr(nbuf, '\t');
114             if (nbuf) {
115                 *nbuf = '\0';
116             }
117         }
118
119         _total++;
120
121         /* Check if it is a file to search everywhere */
122         if (*file == '*') {
123             /* Maximum number of global files reached */
124             if (rk_sys_count >= MAX_RK_SYS) {
125                 merror(MAX_RK_MSG, ARGV0, MAX_RK_SYS);
126             }
127
128             else {
129                 /* Remove all slashes from the file */
130                 file++;
131                 if (*file == '/') {
132                     file++;
133                 }
134
135                 rk_sys_file[rk_sys_count] = strdup(file);
136                 rk_sys_name[rk_sys_count] = strdup(name);
137
138                 if (!rk_sys_name[rk_sys_count] ||
139                         !rk_sys_file[rk_sys_count] ) {
140                     merror(MEM_ERROR, ARGV0, errno, strerror(errno));
141
142                     if (rk_sys_file[rk_sys_count]) {
143                         free(rk_sys_file[rk_sys_count]);
144                     }
145                     if (rk_sys_name[rk_sys_count]) {
146                         free(rk_sys_name[rk_sys_count]);
147                     }
148
149                     rk_sys_file[rk_sys_count] = NULL;
150                     rk_sys_name[rk_sys_count] = NULL;
151                 }
152
153                 rk_sys_count++;
154
155                 /* Always assign the last as NULL */
156                 rk_sys_file[rk_sys_count] = NULL;
157                 rk_sys_name[rk_sys_count] = NULL;
158             }
159             continue;
160         }
161
162         snprintf(file_path, OS_SIZE_1024, "%s/%s", basedir, file);
163
164         if (is_file(file_path)) {
165             char op_msg[OS_SIZE_1024 + 1];
166
167             _errors = 1;
168             snprintf(op_msg, OS_SIZE_1024, "Rootkit '%s' detected "
169                      "by the presence of file '%s'.", name, file_path);
170
171             notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
172         }
173
174 newline:
175         continue;
176     }
177
178     if (_errors == 0) {
179         char op_msg[OS_SIZE_1024 + 1];
180         snprintf(op_msg, OS_SIZE_1024, "No presence of public rootkits detected."
181                  " Analyzed %d files.", _total);
182         notify_rk(ALERT_OK, op_msg);
183     }
184 }
185