1 |
aramv |
526 |
#include "pdl.h" |
2 |
|
|
|
3 |
aramv |
881 |
/* Lex/Yacc stuff */ |
4 |
aramv |
1069 |
extern FILE * yyin; |
5 |
aramv |
1127 |
extern unsigned int lineno; |
6 |
aramv |
1069 |
extern int yyparse(void); |
7 |
|
|
extern int yylex(void); |
8 |
aramv |
1127 |
|
9 |
|
|
/* Lex/Yacc cleanup functions */ |
10 |
aramv |
1069 |
extern void delete_lex_buffer(void); |
11 |
aramv |
1127 |
#if HAVE_YYLEX_DESTROY |
12 |
|
|
extern int yylex_destroy(void); |
13 |
|
|
#endif |
14 |
aramv |
881 |
|
15 |
aramv |
1069 |
/* internal data */ |
16 |
aramv |
1085 |
static const char* config_file_s; |
17 |
aramv |
1077 |
FILE* config_file_fp; |
18 |
aramv |
1069 |
static char* _pdl_path; |
19 |
aramv |
1085 |
|
20 |
|
|
var_t* variables_list; |
21 |
|
|
var_t* variables_list_last; |
22 |
aramv |
1077 |
var_t* current_variable; |
23 |
aramv |
891 |
|
24 |
aramv |
1085 |
rule_t* rules_list; |
25 |
|
|
rule_t* rules_list_last; |
26 |
|
|
rule_t* current_rule; |
27 |
|
|
|
28 |
aramv |
1123 |
policy_t* policies_list; |
29 |
|
|
policy_t* policies_list_last; |
30 |
|
|
policy_t* current_policy; |
31 |
|
|
|
32 |
aramv |
1070 |
/*! initializes the parsing of the configuration file */ |
33 |
aramv |
1077 |
EES_RC pdl_init(const char* config_file_name){ |
34 |
aramv |
1145 |
eef_plugindl_t* temp_plugin = NULL; |
35 |
aramv |
1077 |
config_file_s = config_file_name; |
36 |
aramv |
1145 |
|
37 |
aramv |
1077 |
if((config_file_fp = fopen(config_file_s,"r")) != NULL){ |
38 |
|
|
yyin = config_file_fp; |
39 |
aramv |
592 |
yyparse(); |
40 |
aramv |
1145 |
/*print_policies();*/ |
41 |
aramv |
1142 |
if(add_plugins() == EES_SUCCESS){ |
42 |
|
|
/* this is a callout to the plugin manager, which calls dlopen(), dlsym() and the plugin's initialize function */ |
43 |
|
|
if(initialize_plugins() == EES_SUCCESS){ |
44 |
aramv |
1145 |
temp_plugin = build_plugin_tree(policies_list); |
45 |
|
|
print_plugin_tree_recursive(temp_plugin, 0); |
46 |
|
|
|
47 |
aramv |
1142 |
return EES_SUCCESS; |
48 |
|
|
} else { |
49 |
|
|
eef_log(LOG_ERR, "Failed to initialize plug-ins from policy config file %s\n", config_file_s); |
50 |
|
|
} |
51 |
aramv |
1131 |
} else { |
52 |
aramv |
1142 |
eef_log(LOG_ERR, "Failed to load plug-ins from policy config file %s\n", config_file_s); |
53 |
aramv |
890 |
} |
54 |
aramv |
526 |
} else { |
55 |
aramv |
1142 |
eef_log(LOG_ERR, "Failed to open policy config file %s", config_file_s); |
56 |
aramv |
526 |
} |
57 |
aramv |
1077 |
return EES_FAILURE; |
58 |
aramv |
526 |
} |
59 |
|
|
|
60 |
aramv |
1145 |
/* TODO fix this */ |
61 |
|
|
/* builds a tree of eef_plugindl_t structs, which hold pointers to initialized plugins retrieved from the plugin manager */ |
62 |
|
|
eef_plugindl_t* build_plugin_tree(policy_t* policies){ |
63 |
|
|
policy_t *temp_policy = policies; |
64 |
|
|
eef_plugindl_t *temp_plugin_rule = NULL , *temp_plugin_rule_last = NULL, *plugin_tree = NULL, *plugin_tree_last = NULL, *temp_plugin_node = NULL; |
65 |
|
|
rule_t *temp_rule = NULL; |
66 |
|
|
/*plugin_tree = calloc(1,sizeof(eef_plugindl_t));*/ |
67 |
|
|
char** argv; |
68 |
|
|
int argc; |
69 |
|
|
|
70 |
|
|
while(temp_policy){ |
71 |
|
|
temp_rule = temp_policy->rules; |
72 |
|
|
eef_log(LOG_DEBUG, "Policy: %s\n", temp_policy->name); |
73 |
|
|
while(temp_rule){ |
74 |
|
|
argv = _var_to_argv(get_variable_by_name(temp_rule->state)->value, &argc); |
75 |
|
|
temp_plugin_node = get_plugin(argv[0]); |
76 |
|
|
free_args(argc, argv); |
77 |
|
|
if(temp_plugin_rule){ |
78 |
|
|
temp_plugin_rule_last->next = temp_plugin_node; |
79 |
|
|
} else { |
80 |
|
|
temp_plugin_rule = temp_plugin_node; |
81 |
|
|
} |
82 |
|
|
temp_plugin_rule_last = temp_plugin_node; |
83 |
|
|
|
84 |
|
|
eef_log(LOG_DEBUG, " | Rule %s\n", temp_rule->state); |
85 |
|
|
/*eef_log(LOG_DEBUG, "ARGV[0]: %s\n", argv[0]);*/ |
86 |
|
|
eef_log(LOG_DEBUG, " -------------------------\n"); |
87 |
|
|
|
88 |
|
|
if(temp_plugin_rule_last){ |
89 |
|
|
if(temp_rule->true_branch){ |
90 |
|
|
eef_log(LOG_DEBUG, " True branch: %s\n", temp_rule->true_branch->state); |
91 |
|
|
argv = _var_to_argv(get_variable_by_name(temp_rule->true_branch->state)->value, &argc); |
92 |
|
|
/*eef_log(LOG_DEBUG, "ARGV[0]: %s\n", argv[0]);*/ |
93 |
|
|
temp_plugin_rule_last->true_branch = get_plugin(argv[0]); |
94 |
|
|
free_args(argc, argv); |
95 |
|
|
} |
96 |
|
|
|
97 |
|
|
if(temp_rule->false_branch){ |
98 |
|
|
eef_log(LOG_DEBUG, " False branch: %s\n", temp_rule->false_branch->state); |
99 |
|
|
argv = _var_to_argv(get_variable_by_name(temp_rule->false_branch->state)->value, &argc); |
100 |
|
|
/*eef_log(LOG_DEBUG, "ARGV[0]: %s\n", argv[0]);*/ |
101 |
|
|
temp_plugin_rule_last->false_branch = get_plugin(argv[0]); |
102 |
|
|
free_args(argc, argv); |
103 |
|
|
} |
104 |
|
|
} |
105 |
|
|
|
106 |
|
|
eef_log(LOG_DEBUG, "\n"); |
107 |
|
|
|
108 |
|
|
/* iterate to next rule */ |
109 |
|
|
temp_rule = temp_rule->next; |
110 |
|
|
} |
111 |
|
|
|
112 |
|
|
/* iterate to next policy */ |
113 |
|
|
temp_policy = temp_policy->next; |
114 |
|
|
|
115 |
|
|
/* append to the end of the list */ |
116 |
|
|
if(plugin_tree){ |
117 |
|
|
plugin_tree_last->next = temp_plugin_rule; |
118 |
|
|
} else { |
119 |
|
|
plugin_tree = temp_plugin_rule; |
120 |
|
|
} |
121 |
|
|
plugin_tree_last = temp_plugin_rule; |
122 |
|
|
|
123 |
|
|
} |
124 |
|
|
return plugin_tree; |
125 |
|
|
} |
126 |
|
|
|
127 |
|
|
void free_args(int argc, char** argv){ |
128 |
|
|
for(; argc > 0; argc--){ |
129 |
|
|
free(argv[argc-1]); |
130 |
|
|
} |
131 |
|
|
free(argv); |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
void print_plugin_tree_recursive(eef_plugindl_t* plugin_tree, int depth){ |
135 |
|
|
int depth_cache; |
136 |
|
|
int num_policy = 1; |
137 |
|
|
|
138 |
|
|
while(plugin_tree){ |
139 |
|
|
if(depth==0){ |
140 |
|
|
printf("Policy %i\n", num_policy); |
141 |
|
|
} |
142 |
|
|
|
143 |
|
|
for(depth_cache = depth; depth_cache > 0; depth_cache--){ |
144 |
|
|
printf(" "); |
145 |
|
|
} |
146 |
|
|
printf("| Rule %s\n", plugin_tree->pluginname); |
147 |
|
|
for(depth_cache = depth; depth_cache > 0; depth_cache--){ |
148 |
|
|
printf(" "); |
149 |
|
|
} |
150 |
|
|
printf("-------------------------\n"); |
151 |
|
|
if(plugin_tree->true_branch){ |
152 |
|
|
printf("True: \n"); |
153 |
|
|
print_plugin_tree_recursive(plugin_tree->true_branch, depth+1); |
154 |
|
|
} |
155 |
|
|
if(plugin_tree->false_branch){ |
156 |
|
|
printf("False: \n"); |
157 |
|
|
print_plugin_tree_recursive(plugin_tree->false_branch, depth+1); |
158 |
|
|
} |
159 |
|
|
printf("\n"); |
160 |
|
|
|
161 |
|
|
if(depth==0){ |
162 |
|
|
num_policy++; |
163 |
|
|
/* only iterate top level plugins as only they can be considered policies - that is, they have branches */ |
164 |
|
|
if(plugin_tree->next){ |
165 |
|
|
if(!plugin_tree->next->true_branch || !plugin_tree->next->false_branch){ |
166 |
|
|
plugin_tree = NULL; |
167 |
|
|
} else { |
168 |
|
|
plugin_tree = plugin_tree->next; |
169 |
|
|
} |
170 |
|
|
} |
171 |
|
|
} else { |
172 |
|
|
/* prevent recursive printing of everything below top level plugins */ |
173 |
|
|
plugin_tree = NULL; |
174 |
|
|
} |
175 |
|
|
} |
176 |
|
|
|
177 |
|
|
} |
178 |
|
|
|
179 |
aramv |
1070 |
/*! sets the path to modules directory */ |
180 |
aramv |
1142 |
void set_pdl_path(record_t* path){ |
181 |
aramv |
592 |
size_t path_size = 0; |
182 |
aramv |
867 |
size_t string_size = (sizeof(char) * (strlen(path->string)+2)); /* size of string + extra slash + null byte */ |
183 |
aramv |
881 |
_pdl_path = ""; |
184 |
|
|
|
185 |
aramv |
844 |
/*struct stat sb;*/ |
186 |
|
|
/*if stat(MODUL*/ |
187 |
aramv |
867 |
|
188 |
aramv |
592 |
if(string_size < FILENAME_MAX){ |
189 |
|
|
path_size = string_size; |
190 |
|
|
} else { |
191 |
|
|
path_size = FILENAME_MAX; |
192 |
|
|
} |
193 |
|
|
|
194 |
|
|
if((_pdl_path = calloc(1, path_size))){ |
195 |
|
|
strncpy(_pdl_path, path->string, path_size); |
196 |
aramv |
867 |
strncat(_pdl_path, "/", 1); |
197 |
aramv |
592 |
} |
198 |
aramv |
1070 |
|
199 |
|
|
eef_log(LOG_DEBUG, "Found a new modules path: %s\n", _pdl_path); |
200 |
|
|
|
201 |
aramv |
566 |
free(path->string); |
202 |
|
|
free(path); |
203 |
aramv |
526 |
} |
204 |
|
|
|
205 |
aramv |
1077 |
/*! Handles a variable representing a plug-in; creates a structure containing its values and adds it to the list of var_t structs variables_list */ |
206 |
|
|
void add_variable(record_t* name, record_t* value){ |
207 |
aramv |
1142 |
eef_log(LOG_DEBUG, "Added variable name: %s\n", name->string); |
208 |
|
|
eef_log(LOG_DEBUG, "Added variable value: %s\n", value->string); |
209 |
aramv |
566 |
|
210 |
aramv |
1077 |
/* allocate struct and populate fields */ |
211 |
|
|
if((current_variable = calloc(1,sizeof(var_t)))){ |
212 |
|
|
current_variable->name = strdup(name->string); |
213 |
|
|
current_variable->value = strdup(value->string); |
214 |
|
|
current_variable->lineno = name->lineno; |
215 |
|
|
current_variable->next = NULL; |
216 |
|
|
} else { |
217 |
|
|
eef_log(LOG_ERR, "Out of memory!"); |
218 |
|
|
} |
219 |
aramv |
526 |
|
220 |
aramv |
1077 |
/* append to the end of the list */ |
221 |
|
|
if(variables_list){ |
222 |
|
|
variables_list_last->next = current_variable; |
223 |
|
|
} else { |
224 |
|
|
variables_list = current_variable; |
225 |
aramv |
890 |
} |
226 |
aramv |
1077 |
variables_list_last = current_variable; |
227 |
|
|
|
228 |
|
|
/* clean up */ |
229 |
|
|
free(name->string); |
230 |
|
|
free(name); |
231 |
|
|
free(value->string); |
232 |
|
|
free(value); |
233 |
aramv |
526 |
} |
234 |
|
|
|
235 |
aramv |
1142 |
/* TODO I think this function is a bit of a kludge and could probably be rewritten to be more efficient and more legible - I think it might do too much, so extracting some functions might help */ |
236 |
aramv |
1127 |
/*! Appends a rule to the global rules_list, which is to be added to a policy when add_policy is called |
237 |
|
|
Will return an error when: |
238 |
|
|
- adding the rule to the list will create a recursion in the tree of rules |
239 |
|
|
- an unknown variable is referenced |
240 |
|
|
*/ |
241 |
aramv |
1077 |
rule_t* add_rule(record_t* state, record_t* true_branch, record_t* false_branch){ |
242 |
aramv |
1127 |
rule_t *new_rule = NULL, *new_false_branch = NULL, *new_true_branch = NULL, *recursive_rule = NULL; |
243 |
aramv |
1142 |
var_t *temp_var = NULL; |
244 |
|
|
char *unknown_var_format_string = "Unknown variable %s at line %i in config file %s"; |
245 |
aramv |
1077 |
|
246 |
aramv |
1085 |
if((new_rule = find_state(rules_list, state->string))){ |
247 |
|
|
eef_log(LOG_WARNING, "State %s at line %i is already in use at line %i.\n", state->string, state->lineno, new_rule->lineno); |
248 |
|
|
} else { |
249 |
|
|
/*find variables for rule */ |
250 |
aramv |
1142 |
temp_var = get_variable_by_name(state->string); |
251 |
|
|
if(temp_var == NULL){ |
252 |
|
|
/* Errorous state - variable referenced in rule not previously defined */ |
253 |
|
|
eef_log(LOG_ERR, unknown_var_format_string, state->string, state->lineno, config_file_s); |
254 |
|
|
} |
255 |
|
|
if(temp_var != NULL){ |
256 |
aramv |
1085 |
if((new_rule = calloc(1, sizeof(rule_t)))){ |
257 |
aramv |
1101 |
/* populate fields of current state */ |
258 |
aramv |
1085 |
new_rule->state = strdup(state->string); |
259 |
|
|
new_rule->lineno = state->lineno; |
260 |
|
|
|
261 |
aramv |
1101 |
/* populate fields of branches */ |
262 |
|
|
if(false_branch){ |
263 |
aramv |
1142 |
temp_var = get_variable_by_name(false_branch->string); |
264 |
|
|
if(temp_var == NULL){ |
265 |
|
|
/* Errorous state - variable referenced in rule not previously defined */ |
266 |
|
|
eef_log(LOG_ERR, unknown_var_format_string, false_branch->string, false_branch->lineno, config_file_s); |
267 |
|
|
return NULL; |
268 |
|
|
} |
269 |
aramv |
1101 |
if((new_false_branch = calloc(1, sizeof(rule_t)))){ |
270 |
|
|
new_false_branch->state = strdup(false_branch->string); |
271 |
|
|
new_false_branch->lineno = false_branch->lineno; |
272 |
|
|
new_rule->false_branch = new_false_branch; |
273 |
|
|
} |
274 |
|
|
} |
275 |
aramv |
1127 |
|
276 |
aramv |
1085 |
if(true_branch){ |
277 |
aramv |
1142 |
temp_var = get_variable_by_name(true_branch->string); |
278 |
|
|
if(temp_var == NULL){ |
279 |
|
|
/* Errorous state - variable referenced in rule not previously defined */ |
280 |
|
|
eef_log(LOG_ERR, unknown_var_format_string, true_branch->string, true_branch->lineno, config_file_s); |
281 |
|
|
return NULL; |
282 |
|
|
} |
283 |
aramv |
1101 |
if((new_true_branch = calloc(1, sizeof(rule_t)))){ |
284 |
|
|
new_true_branch->state = strdup(true_branch->string); |
285 |
|
|
new_true_branch->lineno = true_branch->lineno; |
286 |
|
|
new_rule->true_branch = new_true_branch; |
287 |
|
|
} |
288 |
aramv |
1085 |
} |
289 |
|
|
|
290 |
aramv |
1101 |
/* check for recursion */ |
291 |
|
|
if((recursive_rule = check_for_recursion(rules_list, new_rule))){ |
292 |
aramv |
1103 |
eef_log(LOG_WARNING, "Rule %s at line %i leads to recursion into state %s", new_rule->state, new_rule->lineno, recursive_rule->state); |
293 |
aramv |
1085 |
} else { |
294 |
aramv |
1101 |
/* add new rule at the end of the rules list */ |
295 |
|
|
if(rules_list){ |
296 |
|
|
rules_list_last->next = new_rule; |
297 |
|
|
} else { |
298 |
|
|
rules_list = new_rule; |
299 |
|
|
} |
300 |
|
|
rules_list_last = new_rule; |
301 |
aramv |
1123 |
/*eef_log(LOG_DEBUG, "Added a new rule: %s\n", new_rule->state);*/ |
302 |
aramv |
1085 |
} |
303 |
aramv |
1101 |
|
304 |
aramv |
1085 |
} else { |
305 |
|
|
eef_log(LOG_ERR, "Out of memory!"); |
306 |
|
|
} |
307 |
aramv |
1077 |
} |
308 |
aramv |
566 |
} |
309 |
aramv |
1077 |
|
310 |
|
|
/* clean up */ |
311 |
|
|
if(state != NULL){ |
312 |
|
|
free(state->string); |
313 |
|
|
free(state); |
314 |
|
|
} |
315 |
aramv |
566 |
if(true_branch != NULL){ |
316 |
|
|
free(true_branch->string); |
317 |
aramv |
1077 |
free(true_branch); |
318 |
aramv |
566 |
} |
319 |
|
|
if(false_branch != NULL){ |
320 |
|
|
free(false_branch->string); |
321 |
aramv |
1077 |
free(false_branch); |
322 |
aramv |
566 |
} |
323 |
aramv |
1077 |
|
324 |
aramv |
566 |
return new_rule; |
325 |
aramv |
526 |
} |
326 |
|
|
|
327 |
aramv |
1127 |
/* Tries to find a recursion in the list of rules by iterating through all the tree branches. When the same rule is encountered in the current list a recursion has been found */ |
328 |
aramv |
1101 |
rule_t* check_for_recursion(rule_t* rule_l, rule_t* rule_r){ |
329 |
aramv |
1106 |
rule_t* temp_rule = rule_l; |
330 |
aramv |
1112 |
|
331 |
|
|
/* right hand rule leads to its own recursive state */ |
332 |
aramv |
1127 |
/* still need to find a way to reuse the code from the while loop to do this check */ |
333 |
aramv |
1112 |
if(rule_r){ |
334 |
|
|
if(rule_r->true_branch){ |
335 |
|
|
if(strcmp(rule_r->state, rule_r->true_branch->state) == 0){ |
336 |
|
|
return rule_r->true_branch; |
337 |
|
|
} |
338 |
|
|
} |
339 |
|
|
|
340 |
|
|
if(rule_r->false_branch){ |
341 |
|
|
if(strcmp(rule_r->state, rule_r->false_branch->state) == 0){ |
342 |
|
|
return rule_r->false_branch; |
343 |
|
|
} |
344 |
|
|
} |
345 |
|
|
} |
346 |
|
|
|
347 |
aramv |
1127 |
/* iterate list of rules */ |
348 |
aramv |
1106 |
while(temp_rule){ |
349 |
|
|
if((temp_rule != NULL) && (rule_r != NULL)){ |
350 |
|
|
/* left hand and right hand state are equal */ |
351 |
|
|
if(strcmp(temp_rule->state, rule_r->state) == 0){ |
352 |
|
|
return rule_r; |
353 |
aramv |
1101 |
} |
354 |
aramv |
1112 |
|
355 |
aramv |
1106 |
/* start state and true branch of right hand rule are equal */ |
356 |
|
|
if(rule_r->true_branch){ |
357 |
|
|
if(strcmp(temp_rule->state, rule_r->true_branch->state) == 0){ |
358 |
|
|
return rule_r->true_branch; |
359 |
|
|
} |
360 |
|
|
} |
361 |
aramv |
1108 |
|
362 |
|
|
/* start state and false branch of right hand side are equal */ |
363 |
|
|
if(rule_r->false_branch){ |
364 |
|
|
if(strcmp(temp_rule->state, rule_r->false_branch->state) == 0){ |
365 |
|
|
return rule_r->false_branch; |
366 |
|
|
} |
367 |
|
|
} |
368 |
aramv |
1101 |
} |
369 |
aramv |
1127 |
|
370 |
aramv |
1106 |
/* move to next rule */ |
371 |
|
|
temp_rule = temp_rule->next; |
372 |
aramv |
1101 |
} |
373 |
aramv |
1106 |
return NULL; |
374 |
aramv |
1101 |
} |
375 |
|
|
|
376 |
aramv |
1127 |
/*! Tries to find specified state in the rules_list */ |
377 |
aramv |
1085 |
rule_t* find_state(rule_t* rule, const char* state){ |
378 |
|
|
if(!rule || !state){ |
379 |
|
|
return NULL; |
380 |
|
|
} |
381 |
|
|
|
382 |
|
|
/* iterate while the rule isn't associated with the given state */ |
383 |
|
|
while(rule && strcmp(state, rule->state)){ |
384 |
|
|
rule = rule->next; |
385 |
|
|
} |
386 |
|
|
return rule; |
387 |
|
|
} |
388 |
|
|
|
389 |
aramv |
1127 |
/*! Adds a new policy_t structure to the policies_list which will hold the current rules_list. rules_list is nulled after creating a policy so a new list can be created for the next policy */ |
390 |
|
|
void add_policy(record_t* policy, rule_t* top_rule){ |
391 |
aramv |
1123 |
policy_t* new_policy = NULL; |
392 |
|
|
/*eef_log(LOG_DEBUG, "Found a new policy: %s\n", policy->string);*/ |
393 |
aramv |
1077 |
|
394 |
aramv |
1127 |
if((new_policy = calloc(1, sizeof(policy_t)))){ |
395 |
aramv |
1123 |
new_policy->name = strdup(policy->string); |
396 |
|
|
new_policy->lineno = policy->lineno; |
397 |
aramv |
1127 |
new_policy->rules = top_rule; |
398 |
aramv |
1123 |
} |
399 |
|
|
|
400 |
|
|
/* append to the end of the list */ |
401 |
|
|
if(policies_list){ |
402 |
|
|
policies_list_last->next = new_policy; |
403 |
|
|
} else { |
404 |
|
|
policies_list = new_policy; |
405 |
|
|
} |
406 |
|
|
policies_list_last = new_policy; |
407 |
|
|
|
408 |
|
|
rules_list = NULL; |
409 |
|
|
|
410 |
aramv |
1077 |
free(policy->string); |
411 |
|
|
free(policy); |
412 |
aramv |
1123 |
} |
413 |
aramv |
1077 |
|
414 |
aramv |
1142 |
|
415 |
aramv |
1123 |
void print_policies(){ |
416 |
|
|
rule_t* temp_rule = NULL; |
417 |
|
|
policy_t* temp_policy = policies_list; |
418 |
|
|
|
419 |
|
|
while(temp_policy){ |
420 |
|
|
temp_rule = temp_policy->rules; |
421 |
|
|
eef_log(LOG_DEBUG, "Policy: %s\n", temp_policy->name); |
422 |
|
|
while(temp_rule){ |
423 |
|
|
eef_log(LOG_DEBUG, " | Rule %s\n", temp_rule->state); |
424 |
|
|
eef_log(LOG_DEBUG, " -------------------------\n"); |
425 |
|
|
if(temp_rule->true_branch){ |
426 |
|
|
eef_log(LOG_DEBUG, " True branch: %s\n", temp_rule->true_branch->state); |
427 |
|
|
} |
428 |
|
|
/*if(temp_rule->true_branch && temp_rule->false_branch){*/ |
429 |
|
|
/*}*/ |
430 |
|
|
if(temp_rule->false_branch){ |
431 |
|
|
eef_log(LOG_DEBUG, " False branch: %s\n", temp_rule->false_branch->state); |
432 |
|
|
} |
433 |
|
|
eef_log(LOG_DEBUG, "\n"); |
434 |
|
|
temp_rule = temp_rule->next; |
435 |
|
|
} |
436 |
|
|
temp_policy = temp_policy->next; |
437 |
|
|
} |
438 |
aramv |
1077 |
} |
439 |
|
|
|
440 |
|
|
/*! concatenates two strings */ |
441 |
|
|
record_t* concat_strings(record_t* r1, record_t* r2){ |
442 |
|
|
record_t* new_record; |
443 |
aramv |
1123 |
/*eef_log(LOG_DEBUG, "Concating: %s with %s\n", r1->string, r2->string);*/ |
444 |
aramv |
1077 |
if((new_record = malloc(sizeof(record_t)))){ |
445 |
|
|
if((new_record->string = |
446 |
|
|
calloc(1, sizeof(char)*(strlen(r1->string) + strlen(r2->string)+1)))){ |
447 |
|
|
strncat(new_record->string, r1->string, strlen(r1->string)); |
448 |
|
|
strncat(new_record->string, r2->string, strlen(r2->string)); |
449 |
|
|
free(r1->string); |
450 |
|
|
free(r1); |
451 |
|
|
free(r2->string); |
452 |
|
|
free(r2); |
453 |
|
|
return new_record; |
454 |
|
|
} |
455 |
|
|
} |
456 |
|
|
return NULL; |
457 |
|
|
} |
458 |
|
|
|
459 |
|
|
/*! concatenates two strings with a space in between */ |
460 |
|
|
record_t* concat_strings_with_space(record_t *r1, record_t* r2){ |
461 |
|
|
record_t *r; |
462 |
aramv |
1123 |
/*eef_log(LOG_DEBUG, "Concating: %s with %s with spaces\n", r1->string, r2->string);*/ |
463 |
aramv |
1077 |
if((r = malloc(sizeof(record_t)))){ |
464 |
|
|
r->string = calloc(1,(sizeof(char)*(strlen(r1->string)+strlen(r2->string)+2))); |
465 |
|
|
strncat(r->string, r1->string, strlen(r1->string)); |
466 |
|
|
strncat(r->string, " ", 1); |
467 |
|
|
strncat(r->string, r2->string, strlen(r2->string)); |
468 |
|
|
free(r1->string); |
469 |
|
|
free(r1); |
470 |
|
|
free(r2->string); |
471 |
|
|
free(r2); |
472 |
|
|
return r; |
473 |
|
|
} |
474 |
|
|
return NULL; |
475 |
|
|
} |
476 |
|
|
|
477 |
|
|
/*! logs errors encountered during parsing */ |
478 |
|
|
int yyerror(char* string){ |
479 |
|
|
eef_log(LOG_ERR, "Parse error: %s at line %i in config file %s", string, lineno, config_file_s); |
480 |
|
|
return 0; |
481 |
|
|
} |
482 |
|
|
|
483 |
|
|
/*! get variable from list */ |
484 |
|
|
var_t* get_variable_by_name(char* name){ |
485 |
|
|
for(current_variable = variables_list; current_variable != NULL; current_variable = current_variable->next){ |
486 |
|
|
if(!strncmp(name, current_variable->name, strlen(current_variable->name))){ |
487 |
|
|
return current_variable; |
488 |
|
|
} |
489 |
|
|
} |
490 |
|
|
return NULL; |
491 |
|
|
} |
492 |
|
|
|
493 |
aramv |
1070 |
/*TODO*/ |
494 |
|
|
/*! Removes a policy from the list of policies */ |
495 |
aramv |
526 |
void remove_policy(record_t* policy){ |
496 |
aramv |
810 |
eef_log(LOG_DEBUG, "Deleted policy: %s\n", policy->string); |
497 |
aramv |
526 |
free(policy->string); |
498 |
|
|
free(policy); |
499 |
|
|
} |
500 |
|
|
|
501 |
aramv |
1070 |
/*! converts a string to an array of strings by splitting it at each \t delimiter |
502 |
|
|
- overwrites the second argument with a pointer to the number of elements in the array */ |
503 |
aramv |
586 |
char** _var_to_argv(char* value, int *argc){ |
504 |
|
|
char *start_of_arg = NULL, *copy_of_value = NULL, **argv = NULL; |
505 |
|
|
char *delimiters = " \t"; |
506 |
aramv |
592 |
size_t size_of_arg = 0, size_of_array, i = 0; |
507 |
aramv |
586 |
char *str_ptr; |
508 |
|
|
copy_of_value = strdup(value); |
509 |
|
|
size_of_array = (sizeof(char)*(strlen(copy_of_value)+1)); |
510 |
|
|
if((argv = calloc(1, size_of_array)) != NULL){ |
511 |
|
|
start_of_arg = strtok_r(copy_of_value, delimiters, &str_ptr); |
512 |
|
|
while(start_of_arg != NULL){ |
513 |
|
|
size_of_arg = (sizeof(char)*(strlen(start_of_arg)+1)); |
514 |
|
|
if((argv[i] = calloc(1, size_of_arg))){ |
515 |
|
|
memcpy(argv[i], start_of_arg, size_of_arg); |
516 |
|
|
start_of_arg = strtok_r(NULL, delimiters, &str_ptr); |
517 |
|
|
i++; |
518 |
|
|
} |
519 |
|
|
} |
520 |
|
|
} |
521 |
|
|
free(copy_of_value); |
522 |
aramv |
805 |
if(i < ARG_MAX){ |
523 |
|
|
*argc = i; |
524 |
|
|
} else { |
525 |
|
|
*argc = ARG_MAX; |
526 |
|
|
} |
527 |
aramv |
586 |
return argv; |
528 |
aramv |
572 |
} |
529 |
|
|
|
530 |
aramv |
1127 |
/*! returns pdl path found in parsed config file */ |
531 |
aramv |
1077 |
const char* get_pdl_path(){ |
532 |
|
|
return _pdl_path; |
533 |
|
|
} |
534 |
aramv |
890 |
|
535 |
aramv |
1142 |
/*! Iterates list of policies and the rules they contain and tries to add the specified plug-ins to the plugin manager */ |
536 |
|
|
EES_RC add_plugins(){ |
537 |
aramv |
1131 |
char** argv; |
538 |
|
|
int argc; |
539 |
|
|
EES_RC plugin_initialized_ok = EES_SUCCESS; |
540 |
|
|
/*policy_t *temp_policy = policies_list, *last_policy = NULL;*/ |
541 |
|
|
/*rule_t *temp_rule = NULL;*/ |
542 |
|
|
var_t *temp_var = variables_list; |
543 |
|
|
|
544 |
|
|
while((temp_var != NULL) && (plugin_initialized_ok == EES_SUCCESS)){ |
545 |
aramv |
1142 |
/*printf("Var: %s\n", temp_var->name);*/ |
546 |
|
|
/*printf("Plug-in: %s\n", temp_var->value);*/ |
547 |
aramv |
1131 |
argv = _var_to_argv(temp_var->value, &argc); |
548 |
|
|
|
549 |
aramv |
1142 |
/* this is a callout to the plug-in manager, which adds a single plug-in to its list */ |
550 |
|
|
plugin_initialized_ok = add_plugin(argc, argv); |
551 |
aramv |
1131 |
|
552 |
|
|
/* Move to next variable */ |
553 |
|
|
temp_var = temp_var->next; |
554 |
|
|
} |
555 |
|
|
|
556 |
|
|
return plugin_initialized_ok; |
557 |
aramv |
890 |
} |
558 |
|
|
|
559 |
aramv |
1127 |
/*! Iterates the list of var_t structures and tries to free them */ |
560 |
aramv |
1077 |
EES_RC clean_variables_list(){ |
561 |
|
|
current_variable = variables_list; |
562 |
|
|
while(current_variable){ |
563 |
|
|
free(current_variable->name); |
564 |
|
|
free(current_variable->value); |
565 |
aramv |
1085 |
|
566 |
aramv |
1127 |
/* Move to next variable */ |
567 |
aramv |
1085 |
variables_list_last = current_variable; |
568 |
aramv |
1077 |
current_variable = current_variable->next; |
569 |
aramv |
1085 |
|
570 |
aramv |
1127 |
/* Clean last variable struct */ |
571 |
aramv |
1085 |
free(variables_list_last); |
572 |
aramv |
890 |
} |
573 |
|
|
return EES_SUCCESS; |
574 |
|
|
} |
575 |
|
|
|
576 |
aramv |
1127 |
/*! Iterates the list of rule_t structures starting with the passed rule and tries to free them and their true/false branches */ |
577 |
|
|
EES_RC clean_rules_list(rule_t* top_rule){ |
578 |
|
|
rule_t* temp_rule = top_rule; |
579 |
|
|
rule_t* last_rule; |
580 |
|
|
while(temp_rule){ |
581 |
|
|
/* Clean rules in true branch */ |
582 |
|
|
if(temp_rule->true_branch){ |
583 |
|
|
clean_rules_list(temp_rule->true_branch); |
584 |
|
|
} |
585 |
aramv |
1085 |
|
586 |
aramv |
1127 |
/* Clean rules in false branch */ |
587 |
|
|
if(temp_rule->false_branch){ |
588 |
|
|
clean_rules_list(temp_rule->false_branch); |
589 |
|
|
} |
590 |
aramv |
1085 |
|
591 |
aramv |
1127 |
/* Clean rule state */ |
592 |
|
|
free(temp_rule->state); |
593 |
|
|
|
594 |
|
|
/* Move to next rule */ |
595 |
|
|
last_rule = temp_rule; |
596 |
|
|
temp_rule = temp_rule->next; |
597 |
|
|
|
598 |
|
|
/* Clean rule struct */ |
599 |
|
|
free(last_rule); |
600 |
aramv |
1085 |
} |
601 |
|
|
return EES_SUCCESS; |
602 |
|
|
} |
603 |
|
|
|
604 |
aramv |
1127 |
/*! Iterates the list of policy_t structures and tries to free them and their rules */ |
605 |
|
|
EES_RC clean_policies_list(){ |
606 |
|
|
policy_t *temp_policy = policies_list, *last_policy = NULL; |
607 |
|
|
while(temp_policy){ |
608 |
|
|
/* Clean policy fields */ |
609 |
|
|
clean_rules_list(temp_policy->rules); |
610 |
|
|
free(temp_policy->name); |
611 |
|
|
|
612 |
|
|
/* Move to next policy */ |
613 |
|
|
last_policy = temp_policy; |
614 |
|
|
temp_policy = temp_policy->next; |
615 |
|
|
free(last_policy); |
616 |
|
|
} |
617 |
|
|
return EES_SUCCESS; |
618 |
|
|
} |
619 |
|
|
|
620 |
aramv |
1070 |
/*! Terminates the parser and tries to free all used memory */ |
621 |
aramv |
781 |
EES_RC pdl_term(){ |
622 |
aramv |
1077 |
clean_variables_list(); |
623 |
aramv |
1127 |
clean_policies_list(); |
624 |
aramv |
592 |
free(_pdl_path); |
625 |
aramv |
1077 |
|
626 |
|
|
if(config_file_fp != NULL){ |
627 |
aramv |
1069 |
/* This is the preferred way of cleaning up various flex versions - See: http://flex.sourceforge.net/manual/Memory-leak-_002d-16386-bytes-allocated-by-malloc_002e.html#Memory-leak-_002d-16386-bytes-allocated-by-malloc_002e */ |
628 |
aramv |
1127 |
#if HAVE_YYLEX_DESTROY /* macro set by configure script */ |
629 |
aramv |
586 |
yylex_destroy(); |
630 |
aramv |
1069 |
#else |
631 |
aramv |
1127 |
/*eef_log(LOG_WARNING, "Lex function yylex_destroy() not available - possibly unable to free allocated memory for evaluation manager\n");*/ |
632 |
aramv |
1069 |
#if HAVE_FLEX |
633 |
aramv |
1127 |
delete_lex_buffer(); /* this function is defined in pdl_lex.l */ |
634 |
|
|
/*eef_log(LOG_INFO, "Managed to free allocated memory for evaluation manager\n"); */ |
635 |
|
|
#else |
636 |
|
|
eef_log(LOG_WARNING, "Lex functions yylex_destroy() and yy_delete_buffer() are both not available - unable to free allocated memory for evaluation manager\n"); |
637 |
aramv |
1069 |
#endif |
638 |
aramv |
586 |
#endif |
639 |
aramv |
1127 |
|
640 |
aramv |
1077 |
if((fclose(config_file_fp)==0) ){ |
641 |
aramv |
781 |
return EES_SUCCESS; |
642 |
aramv |
586 |
} |
643 |
aramv |
526 |
} |
644 |
aramv |
781 |
return EES_FAILURE; |
645 |
aramv |
526 |
} |
646 |
|
|
|
647 |
aramv |
1070 |
/*! TODO */ |
648 |
aramv |
781 |
EES_RC allow_rules(int val){ |
649 |
aramv |
1127 |
/*printf("Allowed rules: %i\n", val);*/ |
650 |
aramv |
781 |
return EES_SUCCESS; |
651 |
aramv |
526 |
} |
652 |
|
|
|
653 |
aramv |
1070 |
/*! TODO */ |
654 |
aramv |
781 |
EES_RC allowed_policy_rule(const char* label){ |
655 |
aramv |
1127 |
/*printf("Allowed policy rule: %s\n", label);*/ |
656 |
aramv |
781 |
return EES_SUCCESS; |
657 |
aramv |
526 |
} |