PageRenderTime 21ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/src/config/localfile-config.c

https://bitbucket.org/cmoraes/ossec.old
C | 455 lines | 348 code | 69 blank | 38 comment | 121 complexity | 383b6c3bbaca256877f5d347dc3ec6b2 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* @(#) $Id$ */
  2. /* Copyright (C) 2009 Trend Micro Inc.
  3. * All right reserved.
  4. *
  5. * This program is a free software; you can redistribute it
  6. * and/or modify it under the terms of the GNU General Public
  7. * License (version 2) as published by the FSF - Free Software
  8. * Foundation
  9. */
  10. #include "shared.h"
  11. #include "localfile-config.h"
  12. int Read_Localfile(XML_NODE node, void *d1, void *d2)
  13. {
  14. int pl = 0;
  15. int i = 0;
  16. int glob_set = 0;
  17. #ifndef WIN32
  18. int glob_offset = 0;
  19. #endif
  20. /* XML Definitions */
  21. char *xml_localfile_location = "location";
  22. char *xml_localfile_command = "command";
  23. char *xml_localfile_logformat = "log_format";
  24. char *xml_localfile_frequency = "frequency";
  25. char *xml_localfile_alias = "alias";
  26. logreader *logf;
  27. logreader_config *log_config;
  28. log_config = (logreader_config *)d1;
  29. /* If config is not set, we need to create it */
  30. if(!log_config->config)
  31. {
  32. os_calloc(2, sizeof(logreader), log_config->config);
  33. logf = log_config->config;
  34. logf[0].file = NULL;
  35. logf[0].command = NULL;
  36. logf[0].alias = NULL;
  37. logf[0].logformat = NULL;
  38. logf[1].file = NULL;
  39. logf[1].command = NULL;
  40. logf[1].alias = NULL;
  41. logf[1].logformat = NULL;
  42. }
  43. else
  44. {
  45. logf = log_config->config;
  46. while(logf[pl].file != NULL)
  47. {
  48. pl++;
  49. }
  50. /* Allocating more memory */
  51. os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config);
  52. logf = log_config->config;
  53. logf[pl +1].file = NULL;
  54. logf[pl +1].command = NULL;
  55. logf[pl +1].alias = NULL;
  56. logf[pl +1].logformat = NULL;
  57. }
  58. logf[pl].file = NULL;
  59. logf[pl].command = NULL;
  60. logf[pl].alias = NULL;
  61. logf[pl].logformat = NULL;
  62. logf[pl].fp = NULL;
  63. logf[pl].ffile = NULL;
  64. logf[pl].djb_program_name = NULL;
  65. logf[pl].ign = 360;
  66. /* Searching for entries related to files */
  67. i = 0;
  68. while(node[i])
  69. {
  70. if(!node[i]->element)
  71. {
  72. merror(XML_ELEMNULL, ARGV0);
  73. return(OS_INVALID);
  74. }
  75. else if(!node[i]->content)
  76. {
  77. merror(XML_VALUENULL, ARGV0, node[i]->element);
  78. return(OS_INVALID);
  79. }
  80. else if(strcmp(node[i]->element,xml_localfile_command) == 0)
  81. {
  82. /* We don't accept remote commands from the manager - just in case. */
  83. if(log_config->agent_cfg == 1)
  84. {
  85. merror("%s: Remote commands are not accepted from the manager. "
  86. "Ignoring it on the agent.conf", ARGV0);
  87. logf[pl].file = NULL;
  88. logf[pl].ffile = NULL;
  89. logf[pl].command = NULL;
  90. logf[pl].alias = NULL;
  91. logf[pl].logformat = NULL;
  92. logf[pl].fp = NULL;
  93. return(OS_INVALID);
  94. }
  95. os_strdup(node[i]->content, logf[pl].file);
  96. logf[pl].command = logf[pl].file;
  97. }
  98. else if(strcmp(node[i]->element,xml_localfile_frequency) == 0)
  99. {
  100. if(!OS_StrIsNum(node[i]->content))
  101. {
  102. merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
  103. return(OS_INVALID);
  104. }
  105. logf[pl].ign = atoi(node[i]->content);
  106. }
  107. else if(strcmp(node[i]->element,xml_localfile_location) == 0)
  108. {
  109. #ifdef WIN32
  110. /* Expand variables on Windows. */
  111. if(strchr(node[i]->content, '%'))
  112. {
  113. int expandreturn = 0;
  114. char newfile[OS_MAXSTR +1];
  115. newfile[OS_MAXSTR] = '\0';
  116. expandreturn = ExpandEnvironmentStrings(node[i]->content,
  117. newfile, OS_MAXSTR);
  118. if((expandreturn > 0) && (expandreturn < OS_MAXSTR))
  119. {
  120. free(node[i]->content);
  121. os_strdup(newfile, node[i]->content);
  122. }
  123. }
  124. #endif
  125. /* This is a glob*.
  126. * We will call this file multiple times until
  127. * there is no one else available.
  128. */
  129. #ifndef WIN32 /* No windows support for glob */
  130. if(strchr(node[i]->content, '*') ||
  131. strchr(node[i]->content, '?') ||
  132. strchr(node[i]->content, '['))
  133. {
  134. glob_t g;
  135. /* Setting ot the first entry of the glob */
  136. if(glob_set == 0)
  137. glob_set = pl +1;
  138. if(glob(node[i]->content, 0, NULL, &g) != 0)
  139. {
  140. merror(GLOB_ERROR, ARGV0, node[i]->content);
  141. os_strdup(node[i]->content, logf[pl].file);
  142. i++;
  143. continue;
  144. }
  145. /* Checking for the last entry */
  146. if((g.gl_pathv[glob_offset]) == NULL)
  147. {
  148. /* Checking when nothing is found. */
  149. if(glob_offset == 0)
  150. {
  151. merror(GLOB_NFOUND, ARGV0, node[i]->content);
  152. return(OS_INVALID);
  153. }
  154. i++;
  155. continue;
  156. }
  157. /* Checking for strftime on globs too. */
  158. if(strchr(g.gl_pathv[glob_offset], '%'))
  159. {
  160. struct tm *p;
  161. time_t l_time = time(0);
  162. char lfile[OS_FLSIZE + 1];
  163. size_t ret;
  164. p = localtime(&l_time);
  165. lfile[OS_FLSIZE] = '\0';
  166. ret = strftime(lfile, OS_FLSIZE, g.gl_pathv[glob_offset], p);
  167. if(ret == 0)
  168. {
  169. merror(PARSE_ERROR, ARGV0, g.gl_pathv[glob_offset]);
  170. return(OS_INVALID);
  171. }
  172. os_strdup(g.gl_pathv[glob_offset], logf[pl].ffile);
  173. os_strdup(g.gl_pathv[glob_offset], logf[pl].file);
  174. }
  175. else
  176. {
  177. os_strdup(g.gl_pathv[glob_offset], logf[pl].file);
  178. }
  179. glob_offset++;
  180. globfree(&g);
  181. /* Now we need to create another file entry */
  182. pl++;
  183. os_realloc(logf, (pl +2)*sizeof(logreader), log_config->config);
  184. logf = log_config->config;
  185. logf[pl].file = NULL;
  186. logf[pl].alias = NULL;
  187. logf[pl].logformat = NULL;
  188. logf[pl].fp = NULL;
  189. logf[pl].ffile = NULL;
  190. logf[pl +1].file = NULL;
  191. logf[pl +1].alias = NULL;
  192. logf[pl +1].logformat = NULL;
  193. /* We can not increment the file count in here */
  194. continue;
  195. }
  196. else if(strchr(node[i]->content, '%'))
  197. #else
  198. if(strchr(node[i]->content, '%'))
  199. #endif /* WIN32 */
  200. /* We need the format file (based on date) */
  201. {
  202. struct tm *p;
  203. time_t l_time = time(0);
  204. char lfile[OS_FLSIZE + 1];
  205. size_t ret;
  206. p = localtime(&l_time);
  207. lfile[OS_FLSIZE] = '\0';
  208. ret = strftime(lfile, OS_FLSIZE, node[i]->content, p);
  209. if(ret == 0)
  210. {
  211. merror(PARSE_ERROR, ARGV0, node[i]->content);
  212. return(OS_INVALID);
  213. }
  214. os_strdup(node[i]->content, logf[pl].ffile);
  215. os_strdup(node[i]->content, logf[pl].file);
  216. }
  217. /* Normal file */
  218. else
  219. {
  220. os_strdup(node[i]->content, logf[pl].file);
  221. }
  222. }
  223. /* Getting log format */
  224. else if(strcasecmp(node[i]->element,xml_localfile_logformat) == 0)
  225. {
  226. os_strdup(node[i]->content, logf[pl].logformat);
  227. if(strcmp(logf[pl].logformat, "syslog") == 0)
  228. {
  229. }
  230. else if(strcmp(logf[pl].logformat, "generic") == 0)
  231. {
  232. }
  233. else if(strcmp(logf[pl].logformat, "snort-full") == 0)
  234. {
  235. }
  236. else if(strcmp(logf[pl].logformat, "snort-fast") == 0)
  237. {
  238. }
  239. else if(strcmp(logf[pl].logformat, "apache") == 0)
  240. {
  241. }
  242. else if(strcmp(logf[pl].logformat, "iis") == 0)
  243. {
  244. }
  245. else if(strcmp(logf[pl].logformat, "squid") == 0)
  246. {
  247. }
  248. else if(strcmp(logf[pl].logformat, "nmapg") == 0)
  249. {
  250. }
  251. else if(strcmp(logf[pl].logformat, "mysql_log") == 0)
  252. {
  253. }
  254. else if(strcmp(logf[pl].logformat, "mssql_log") == 0)
  255. {
  256. }
  257. else if(strcmp(logf[pl].logformat, "postgresql_log") == 0)
  258. {
  259. }
  260. else if(strcmp(logf[pl].logformat, "djb-multilog") == 0)
  261. {
  262. }
  263. else if(strcmp(logf[pl].logformat, "syslog-pipe") == 0)
  264. {
  265. }
  266. else if(strcmp(logf[pl].logformat, "command") == 0)
  267. {
  268. }
  269. else if(strcmp(logf[pl].logformat, "full_command") == 0)
  270. {
  271. }
  272. else if(strncmp(logf[pl].logformat, "multi-line", 10) == 0)
  273. {
  274. int x = 0;
  275. logf[pl].logformat+=10;
  276. while(logf[pl].logformat[0] == ' ')
  277. logf[pl].logformat++;
  278. if(logf[pl].logformat[0] != ':')
  279. {
  280. merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
  281. return(OS_INVALID);
  282. }
  283. logf[pl].logformat++;
  284. while(*logf[pl].logformat == ' ')
  285. logf[pl].logformat++;
  286. while(logf[pl].logformat[x] >= '0' && logf[pl].logformat[x] <= '9')
  287. x++;
  288. while(logf[pl].logformat[x] == ' ')
  289. x++;
  290. if(logf[pl].logformat[x] != '\0')
  291. {
  292. merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
  293. return(OS_INVALID);
  294. }
  295. }
  296. else if(strcmp(logf[pl].logformat, EVENTLOG) == 0)
  297. {
  298. }
  299. else
  300. {
  301. merror(XML_VALUEERR,ARGV0,node[i]->element,node[i]->content);
  302. return(OS_INVALID);
  303. }
  304. }
  305. else if(strcasecmp(node[i]->element,xml_localfile_alias) == 0)
  306. {
  307. os_strdup(node[i]->content, logf[pl].alias);
  308. }
  309. else
  310. {
  311. merror(XML_INVELEM, ARGV0, node[i]->element);
  312. return(OS_INVALID);
  313. }
  314. i++;
  315. }
  316. /* Validating glob entries */
  317. if(glob_set)
  318. {
  319. char *format;
  320. /* Getting log format */
  321. if(logf[pl].logformat)
  322. {
  323. format = logf[pl].logformat;
  324. }
  325. else if(logf[glob_set -1].logformat)
  326. {
  327. format = logf[glob_set -1].logformat;
  328. }
  329. else
  330. {
  331. merror(MISS_LOG_FORMAT, ARGV0);
  332. return(OS_INVALID);
  333. }
  334. /* The last entry is always null on glob */
  335. pl--;
  336. /* Setting format for all entries */
  337. for(i = (glob_set -1); i<= pl; i++)
  338. {
  339. /* Every entry must be valid */
  340. if(!logf[i].file)
  341. {
  342. merror(MISS_FILE, ARGV0);
  343. return(OS_INVALID);
  344. }
  345. if(logf[i].logformat == NULL)
  346. {
  347. logf[i].logformat = format;
  348. }
  349. }
  350. }
  351. /* Missing log format */
  352. if(!logf[pl].logformat)
  353. {
  354. merror(MISS_LOG_FORMAT, ARGV0);
  355. return(OS_INVALID);
  356. }
  357. /* Missing file */
  358. if(!logf[pl].file)
  359. {
  360. merror(MISS_FILE, ARGV0);
  361. return(OS_INVALID);
  362. }
  363. /* Verifying a valid event log config */
  364. if(strcmp(logf[pl].logformat, EVENTLOG) == 0)
  365. {
  366. if((strcmp(logf[pl].file, "Application") != 0)&&
  367. (strcmp(logf[pl].file, "System") != 0)&&
  368. (strcmp(logf[pl].file, "Security") != 0))
  369. {
  370. /* Invalid event log */
  371. merror(NSTD_EVTLOG, ARGV0, logf[pl].file);
  372. return(0);
  373. }
  374. }
  375. if((strcmp(logf[pl].logformat, "command") == 0)||
  376. (strcmp(logf[pl].logformat, "full_command") == 0))
  377. {
  378. if(!logf[pl].command)
  379. {
  380. merror("%s: ERROR: Missing 'command' argument. "
  381. "This option will be ignored.", ARGV0);
  382. }
  383. }
  384. return(0);
  385. }
  386. /* EOF */