1 /* @(#) $Id: ./src/config/localfile-config.c, 2012/03/28 dcid Exp $
4 /* Copyright (C) 2009 Trend Micro Inc.
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
16 #include "localfile-config.h"
19 int Read_Localfile(XML_NODE node, void *d1, void *d2)
32 char *xml_localfile_location = "location";
33 char *xml_localfile_command = "command";
34 char *xml_localfile_logformat = "log_format";
35 char *xml_localfile_frequency = "frequency";
36 char *xml_localfile_alias = "alias";
37 char *xml_localfile_future = "only-future-events";
38 char *xml_localfile_query = "query";
41 logreader_config *log_config;
43 log_config = (logreader_config *)d1;
46 /* If config is not set, we need to create it */
47 if(!log_config->config)
49 os_calloc(2, sizeof(logreader), log_config->config);
50 logf = log_config->config;
52 logf[0].command = NULL;
54 logf[0].logformat = NULL;
58 logf[1].command = NULL;
60 logf[1].logformat = NULL;
66 logf = log_config->config;
67 while(logf[pl].file != NULL)
72 /* Allocating more memory */
73 os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config);
74 logf = log_config->config;
75 logf[pl +1].file = NULL;
76 logf[pl +1].command = NULL;
77 logf[pl +1].alias = NULL;
78 logf[pl +1].logformat = NULL;
79 logf[pl +1].future = 0;
80 logf[pl +1].query = NULL;
84 logf[pl].command = NULL;
85 logf[pl].alias = NULL;
86 logf[pl].logformat = NULL;
88 logf[pl].query = NULL;
90 logf[pl].ffile = NULL;
91 logf[pl].djb_program_name = NULL;
95 /* Searching for entries related to files */
101 merror(XML_ELEMNULL, ARGV0);
104 else if(!node[i]->content)
106 merror(XML_VALUENULL, ARGV0, node[i]->element);
109 else if(strcmp(node[i]->element,xml_localfile_future) == 0)
111 if (strcmp(node[i]->content, "yes") == 0)
114 else if(strcmp(node[i]->element,xml_localfile_query) == 0)
116 os_strdup(node[i]->content, logf[pl].query);
118 else if(strcmp(node[i]->element,xml_localfile_command) == 0)
120 /* We don't accept remote commands from the manager - just in case. */
121 if(log_config->agent_cfg == 1 && log_config->accept_remote == 0)
123 merror("%s: Remote commands are not accepted from the manager. "
124 "Ignoring it on the agent.conf", ARGV0);
126 logf[pl].file = NULL;
127 logf[pl].ffile = NULL;
128 logf[pl].command = NULL;
129 logf[pl].alias = NULL;
130 logf[pl].logformat = NULL;
135 os_strdup(node[i]->content, logf[pl].file);
136 logf[pl].command = logf[pl].file;
138 else if(strcmp(node[i]->element,xml_localfile_frequency) == 0)
140 if(!OS_StrIsNum(node[i]->content))
142 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
146 logf[pl].ign = atoi(node[i]->content);
148 else if(strcmp(node[i]->element,xml_localfile_location) == 0)
151 /* Expand variables on Windows. */
152 if(strchr(node[i]->content, '%'))
154 int expandreturn = 0;
155 char newfile[OS_MAXSTR +1];
157 newfile[OS_MAXSTR] = '\0';
158 expandreturn = ExpandEnvironmentStrings(node[i]->content,
161 if((expandreturn > 0) && (expandreturn < OS_MAXSTR))
163 free(node[i]->content);
165 os_strdup(newfile, node[i]->content);
172 * We will call this file multiple times until
173 * there is no one else available.
175 #ifndef WIN32 /* No windows support for glob */
176 if(strchr(node[i]->content, '*') ||
177 strchr(node[i]->content, '?') ||
178 strchr(node[i]->content, '['))
182 /* Setting ot the first entry of the glob */
186 if(glob(node[i]->content, 0, NULL, &g) != 0)
188 merror(GLOB_ERROR, ARGV0, node[i]->content);
189 os_strdup(node[i]->content, logf[pl].file);
194 /* Checking for the last entry */
195 if((g.gl_pathv[glob_offset]) == NULL)
197 /* Checking when nothing is found. */
200 merror(GLOB_NFOUND, ARGV0, node[i]->content);
208 /* Checking for strftime on globs too. */
209 if(strchr(g.gl_pathv[glob_offset], '%'))
212 time_t l_time = time(0);
213 char lfile[OS_FLSIZE + 1];
216 p = localtime(&l_time);
218 lfile[OS_FLSIZE] = '\0';
219 ret = strftime(lfile, OS_FLSIZE, g.gl_pathv[glob_offset], p);
222 merror(PARSE_ERROR, ARGV0, g.gl_pathv[glob_offset]);
226 os_strdup(g.gl_pathv[glob_offset], logf[pl].ffile);
227 os_strdup(g.gl_pathv[glob_offset], logf[pl].file);
231 os_strdup(g.gl_pathv[glob_offset], logf[pl].file);
238 /* Now we need to create another file entry */
240 os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config);
241 logf = log_config->config;
243 logf[pl].file = NULL;
244 logf[pl].alias = NULL;
245 logf[pl].logformat = NULL;
247 logf[pl].ffile = NULL;
249 logf[pl +1].file = NULL;
250 logf[pl +1].alias = NULL;
251 logf[pl +1].logformat = NULL;
253 /* We can not increment the file count in here */
256 else if(strchr(node[i]->content, '%'))
258 if(strchr(node[i]->content, '%'))
261 /* We need the format file (based on date) */
264 time_t l_time = time(0);
265 char lfile[OS_FLSIZE + 1];
268 p = localtime(&l_time);
270 lfile[OS_FLSIZE] = '\0';
271 ret = strftime(lfile, OS_FLSIZE, node[i]->content, p);
274 os_strdup(node[i]->content, logf[pl].ffile);
277 os_strdup(node[i]->content, logf[pl].file);
284 os_strdup(node[i]->content, logf[pl].file);
288 /* Getting log format */
289 else if(strcasecmp(node[i]->element,xml_localfile_logformat) == 0)
291 os_strdup(node[i]->content, logf[pl].logformat);
293 if(strcmp(logf[pl].logformat, "syslog") == 0)
296 else if(strcmp(logf[pl].logformat, "generic") == 0)
299 else if(strcmp(logf[pl].logformat, "snort-full") == 0)
302 else if(strcmp(logf[pl].logformat, "snort-fast") == 0)
305 else if(strcmp(logf[pl].logformat, "apache") == 0)
308 else if(strcmp(logf[pl].logformat, "iis") == 0)
311 else if(strcmp(logf[pl].logformat, "squid") == 0)
314 else if(strcmp(logf[pl].logformat, "nmapg") == 0)
317 else if(strcmp(logf[pl].logformat, "mysql_log") == 0)
320 else if(strcmp(logf[pl].logformat, "ossecalert") == 0)
323 else if(strcmp(logf[pl].logformat, "mssql_log") == 0)
326 else if(strcmp(logf[pl].logformat, "postgresql_log") == 0)
329 else if(strcmp(logf[pl].logformat, "djb-multilog") == 0)
332 else if(strcmp(logf[pl].logformat, "syslog-pipe") == 0)
335 else if(strcmp(logf[pl].logformat, "command") == 0)
338 else if(strcmp(logf[pl].logformat, "full_command") == 0)
341 else if(strncmp(logf[pl].logformat, "multi-line", 10) == 0)
344 logf[pl].logformat+=10;
346 while(logf[pl].logformat[0] == ' ')
347 logf[pl].logformat++;
349 if(logf[pl].logformat[0] != ':')
351 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
354 logf[pl].logformat++;
356 while(*logf[pl].logformat == ' ')
357 logf[pl].logformat++;
359 while(logf[pl].logformat[x] >= '0' && logf[pl].logformat[x] <= '9')
362 while(logf[pl].logformat[x] == ' ')
365 if(logf[pl].logformat[x] != '\0')
367 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
371 else if(strcmp(logf[pl].logformat, EVENTLOG) == 0)
374 else if(strcmp(logf[pl].logformat, EVENTCHANNEL) == 0)
379 merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
383 else if(strcasecmp(node[i]->element,xml_localfile_alias) == 0)
385 os_strdup(node[i]->content, logf[pl].alias);
389 merror(XML_INVELEM, ARGV0, node[i]->element);
397 /* Validating glob entries */
402 /* Getting log format */
403 if(logf[pl].logformat)
405 format = logf[pl].logformat;
407 else if(logf[glob_set -1].logformat)
409 format = logf[glob_set -1].logformat;
413 merror(MISS_LOG_FORMAT, ARGV0);
417 /* The last entry is always null on glob */
421 /* Setting format for all entries */
422 for(i = (glob_set -1); i<= pl; i++)
424 /* Every entry must be valid */
427 merror(MISS_FILE, ARGV0);
431 if(logf[i].logformat == NULL)
433 logf[i].logformat = format;
439 /* Missing log format */
440 if(!logf[pl].logformat)
442 merror(MISS_LOG_FORMAT, ARGV0);
449 merror(MISS_FILE, ARGV0);
453 /* Verifying a valid event log config */
454 if(strcmp(logf[pl].logformat, EVENTLOG) == 0)
456 if((strcmp(logf[pl].file, "Application") != 0)&&
457 (strcmp(logf[pl].file, "System") != 0)&&
458 (strcmp(logf[pl].file, "Security") != 0))
460 /* Invalid event log */
461 merror(NSTD_EVTLOG, ARGV0, logf[pl].file);
466 if((strcmp(logf[pl].logformat, "command") == 0)||
467 (strcmp(logf[pl].logformat, "full_command") == 0))
469 if(!logf[pl].command)
471 merror("%s: ERROR: Missing 'command' argument. "
472 "This option will be ignored.", ARGV0);