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
10 /* Rootcheck decoder */
13 #include "os_regex/os_regex.h"
14 #include "eventinfo.h"
15 #include "alerts/alerts.h"
18 #define ROOTCHECK_DIR "/queue/rootcheck"
21 static char *rk_agent_ips[MAX_AGENTS];
22 static FILE *rk_agent_fps[MAX_AGENTS];
25 /* Rootcheck decoder */
26 static OSDecoderInfo *rootcheck_dec = NULL;
29 /* Initialize the necessary information to process the rootcheck information */
36 for (; i < MAX_AGENTS; i++) {
37 rk_agent_ips[i] = NULL;
38 rk_agent_fps[i] = NULL;
42 os_calloc(1, sizeof(OSDecoderInfo), rootcheck_dec);
43 rootcheck_dec->id = getDecoderfromlist(ROOTCHECK_MOD);
44 rootcheck_dec->type = OSSEC_RL;
45 rootcheck_dec->name = ROOTCHECK_MOD;
46 rootcheck_dec->fts = 0;
48 debug1("%s: RootcheckInit completed.", ARGV0);
53 /* Return the file pointer to be used */
54 static FILE *RK_File(const char *agent, int *agent_id)
57 char rk_buf[OS_SIZE_1024 + 1];
59 while (rk_agent_ips[i] != NULL) {
60 if (strcmp(rk_agent_ips[i], agent) == 0) {
61 /* Pointing to the beginning of the file */
62 fseek(rk_agent_fps[i], 0, SEEK_SET);
64 return (rk_agent_fps[i]);
70 /* If here, our agent wasn't found */
71 rk_agent_ips[i] = strdup(agent);
73 if (rk_agent_ips[i] != NULL) {
74 snprintf(rk_buf, OS_SIZE_1024, "%s/%s", ROOTCHECK_DIR, agent);
76 /* r+ to read and write. Do not truncate */
77 rk_agent_fps[i] = fopen(rk_buf, "r+");
78 if (!rk_agent_fps[i]) {
79 /* Try opening with a w flag, file probably does not exist */
80 rk_agent_fps[i] = fopen(rk_buf, "w");
81 if (rk_agent_fps[i]) {
82 fclose(rk_agent_fps[i]);
83 rk_agent_fps[i] = fopen(rk_buf, "r+");
86 if (!rk_agent_fps[i]) {
87 merror(FOPEN_ERROR, ARGV0, rk_buf, errno, strerror(errno));
89 free(rk_agent_ips[i]);
90 rk_agent_ips[i] = NULL;
95 /* Return the opened pointer (the beginning of it) */
96 fseek(rk_agent_fps[i], 0, SEEK_SET);
98 return (rk_agent_fps[i]);
102 merror(MEM_ERROR, ARGV0, errno, strerror(errno));
109 /* Special decoder for rootcheck
110 * Not using the default rendering tools for simplicity
111 * and to be less resource intensive
113 int DecodeRootcheck(Eventinfo *lf)
118 char rk_buf[OS_SIZE_2048 + 1];
126 rk_buf[OS_SIZE_2048] = '\0';
128 fp = RK_File(lf->location, &agent_id);
131 merror("%s: Error handling rootcheck database.", ARGV0);
137 /* Get initial position */
138 if (fgetpos(fp, &fp_pos) == -1) {
139 merror("%s: Error handling rootcheck database (fgetpos).", ARGV0);
144 /* Reads the file and search for a possible entry */
145 while (fgets(rk_buf, OS_SIZE_2048 - 1, fp) != NULL) {
146 /* Ignore blank lines and lines with a comment */
147 if (rk_buf[0] == '\n' || rk_buf[0] == '#') {
148 if (fgetpos(fp, &fp_pos) == -1) {
149 merror("%s: Error handling rootcheck database "
150 "(fgetpos2).", ARGV0);
157 tmpstr = strchr(rk_buf, '\n');
162 /* Old format without the time stamps */
163 if (rk_buf[0] != '!') {
164 /* Cannot use strncmp to avoid errors with crafted files */
165 if (strcmp(lf->log, rk_buf) == 0) {
166 rootcheck_dec->fts = 0;
167 lf->decoder_info = rootcheck_dec;
173 /* Going past time: !1183431603!1183431603 (last, first seen) */
174 tmpstr = rk_buf + 23;
176 /* Matches, we need to upgrade last time saw */
177 if (strcmp(lf->log, tmpstr) == 0) {
178 if(fsetpos(fp, &fp_pos)) {
179 merror("%s: Error handling rootcheck database "
180 "(fsetpos).", ARGV0);
183 fprintf(fp, "!%ld", (long int)lf->time);
184 rootcheck_dec->fts = 0;
185 lf->decoder_info = rootcheck_dec;
190 /* Get current position */
191 if (fgetpos(fp, &fp_pos) == -1) {
192 merror("%s: Error handling rootcheck database (fgetpos3).", ARGV0);
197 /* Add the new entry at the end of the file */
198 fseek(fp, 0, SEEK_END);
199 fprintf(fp, "!%ld!%ld %s\n", (long int)lf->time, (long int)lf->time, lf->log);
202 rootcheck_dec->fts = 0;
203 rootcheck_dec->fts |= FTS_DONE;
204 lf->decoder_info = rootcheck_dec;