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
14 #include "global-config.h"
18 static int cmpr(const void *a, const void *b) __attribute__((nonnull));
19 static int file_in_list(unsigned int list_size, char *f_name, char *d_name, char **alist) __attribute__((nonnull));
22 static int cmpr(const void *a, const void *b)
24 return strcmp(*(const char *const *)a, *(const char *const *)b);
27 static int file_in_list(unsigned int list_size, char *f_name, char *d_name, char **alist)
30 for (i = 0; (i + 1) < list_size; i++) {
31 if ((strcmp(alist[i], f_name) == 0 || strcmp(alist[i], d_name) == 0)) {
38 int Read_Rules(XML_NODE node, void *configp, __attribute__((unused)) void *mailp)
43 unsigned int rules_size = 1;
44 unsigned int lists_size = 1;
45 unsigned int decoders_size = 1;
47 char path[PATH_MAX + 2];
48 char f_name[PATH_MAX + 2];
49 unsigned int start_point = 0;
56 const char *xml_rules_include = "include";
57 const char *xml_rules_rule = "rule";
58 const char *xml_rules_rules_dir = "rule_dir";
59 const char *xml_rules_lists = "list";
60 const char *xml_rules_decoders = "decoder";
61 const char *xml_rules_decoders_dir = "decoder_dir";
65 Config = (_Config *)configp;
67 /* Initialize OSRegex */
68 memset(®ex, 0, sizeof(regex));
71 if (!node[i]->element) {
72 merror(XML_ELEMNULL, __local_name);
74 } else if (!node[i]->content) {
75 merror(XML_VALUENULL, __local_name, node[i]->element);
78 /* Mail notification */
79 else if ((strcmp(node[i]->element, xml_rules_include) == 0) ||
80 (strcmp(node[i]->element, xml_rules_rule) == 0)) {
82 Config->includes = (char **) realloc(Config->includes,
83 sizeof(char *)*rules_size);
84 if (!Config->includes) {
85 merror(MEM_ERROR, __local_name, errno, strerror(errno));
89 os_strdup(node[i]->content, Config->includes[rules_size - 2]);
90 Config->includes[rules_size - 1] = NULL;
91 debug1("adding rule: %s", node[i]->content);
92 } else if (strcmp(node[i]->element, xml_rules_decoders) == 0) {
94 Config->decoders = (char **) realloc(Config->decoders,
95 sizeof(char *)*decoders_size);
96 if (!Config->decoders) {
97 merror(MEM_ERROR, __local_name, errno, strerror(errno));
101 os_strdup(node[i]->content, Config->decoders[decoders_size - 2]);
102 Config->decoders[decoders_size - 1] = NULL;
103 debug1("adding decoder: %s", node[i]->content);
104 } else if (strcmp(node[i]->element, xml_rules_lists) == 0) {
106 Config->lists = (char **) realloc(Config->lists,
107 sizeof(char *)*lists_size);
108 if (!Config->lists) {
109 merror(MEM_ERROR, __local_name, errno, strerror(errno));
112 os_strdup(node[i]->content, Config->lists[lists_size - 2]);
113 Config->lists[lists_size - 1] = NULL;
115 } else if (strcmp(node[i]->element, xml_rules_decoders_dir) == 0) {
117 if (node[i]->attributes && node[i]->values) {
118 while (node[i]->attributes[att_count]) {
119 if ((strcasecmp(node[i]->attributes[att_count], "pattern") == 0)) {
120 if (node[i]->values[att_count]) {
121 if (!OSRegex_Compile(node[i]->values[att_count], ®ex, 0)) {
122 merror(CONFIG_ERROR, __local_name, "pattern in decoders_dir does not compile");
123 merror("%s: ERROR: Regex would not compile", __local_name);
131 OSRegex_Compile(".xml$", ®ex, 0);
135 snprintf(path, PATH_MAX + 1, "%s", node[i]->content);
137 snprintf(path, PATH_MAX + 1, "%s/%s", DEFAULTDIR, node[i]->content);
140 f_name[PATH_MAX + 1] = '\0';
143 att_count = 0; // Reset this variable after it was used in decoder
146 start_point = decoders_size - 1;
147 while ((entry = readdir(dfd)) != NULL) {
148 snprintf(f_name, PATH_MAX + 1, "%s/%s", node[i]->content, entry->d_name);
150 /* Ignore . and .. */
151 if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
155 /* No duplicates allowed */
156 if (file_in_list(decoders_size, f_name, entry->d_name, Config->decoders)) {
160 if (OSRegex_Execute(f_name, ®ex)) {
162 Config->decoders = (char **) realloc(Config->decoders, sizeof(char *)*decoders_size);
163 if (!Config->decoders) {
164 merror(MEM_ERROR, __local_name, errno, strerror(errno));
165 OSRegex_FreePattern(®ex);
170 os_strdup(f_name, Config->decoders[decoders_size - 2]);
171 Config->decoders[decoders_size - 1] = NULL;
172 debug1("adding decoder: %s", f_name);
174 debug1("Regex does not match \"%s\"", f_name);
178 OSRegex_FreePattern(®ex);
180 /* Sort just then newly added items */
181 qsort(Config->decoders + start_point , decoders_size - start_point - 1, sizeof(char *), cmpr);
183 debug1("decoders_size %d", decoders_size);
184 for (ii = 0; ii < decoders_size - 1; ii++) {
185 debug1("- %s", Config->decoders[ii]);
187 } else if (strcmp(node[i]->element, xml_rules_rules_dir) == 0) {
188 if (node[i]->attributes && node[i]->values) {
189 while (node[i]->attributes[att_count]) {
190 if ((strcasecmp(node[i]->attributes[att_count], "pattern") == 0)) {
191 if (node[i]->values[att_count]) {
192 if (!OSRegex_Compile(node[i]->values[att_count], ®ex, 0)) {
193 merror(CONFIG_ERROR, __local_name, "pattern in rules_dir does not compile");
194 merror("%s: ERROR: Regex would not compile", __local_name);
202 OSRegex_Compile(".xml$", ®ex, 0);
206 snprintf(path, PATH_MAX + 1, "%s", node[i]->content);
208 snprintf(path, PATH_MAX + 1, "%s/%s", DEFAULTDIR, node[i]->content);
211 f_name[PATH_MAX + 1] = '\0';
215 start_point = rules_size - 1;
216 while ((entry = readdir(dfd)) != NULL) {
217 snprintf(f_name, PATH_MAX + 1, "%s/%s", node[i]->content, entry->d_name);
219 /* Ignore . and .. */
220 if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
224 /* No duplicates allowed */
225 if (file_in_list(rules_size, f_name, entry->d_name, Config->includes)) {
229 if (OSRegex_Execute(f_name, ®ex)) {
231 Config->includes = (char **) realloc(Config->includes, sizeof(char *)*rules_size);
232 if (!Config->includes) {
233 merror(MEM_ERROR, __local_name, errno, strerror(errno));
234 OSRegex_FreePattern(®ex);
239 os_strdup(f_name, Config->includes[rules_size - 2]);
240 Config->includes[rules_size - 1] = NULL;
241 debug1("adding rule: %s", f_name);
243 debug1("Regex does not match \"%s\"", f_name);
247 OSRegex_FreePattern(®ex);
249 /* Sort just then newly added items */
250 qsort(Config->includes + start_point , rules_size - start_point - 1, sizeof(char *), cmpr);
253 merror(XML_INVELEM, __local_name, node[i]->element);
254 OSRegex_FreePattern(®ex);