1 /*
2  * AIDE (Advanced Intrusion Detection Environment)
3  *
4  * Copyright (C) 2019-2021 Hannes von Haugwitz
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "conf_ast.h"
25 #include "conf_lex.h"
26 #include "log.h"
27 #include "util.h"
28 
29 LOG_LEVEL ast_log_level = LOG_LEVEL_DEBUG;
30 
new_ast_node()31 static ast* new_ast_node() {
32     ast* a = checked_malloc(sizeof(ast));
33 
34     a->linenumber = conf_linenumber;
35     a->filename = conf_filename;
36     a->linebuf = conf_linebuf;
37     a->next = NULL;
38 
39     return a;
40 }
41 
new_string_option_statement(config_option option,string_expression * value)42 ast* new_string_option_statement(config_option option, string_expression* value) {
43       ast* a = new_ast_node();
44 
45       a->type = config_option_type;
46       a->statement._config.option = option;
47       a->statement._config.a = NULL;
48       a->statement._config.e = value;
49       log_msg(ast_log_level, "ast: new string option statement (%p): option: %d, value: %p", a, option, value);
50       return a;
51 }
52 
new_attribute_option_statement(config_option option,attribute_expression * value)53 ast* new_attribute_option_statement(config_option option, attribute_expression* value) {
54       ast* a = new_ast_node();
55 
56       a->type = config_option_type;
57       a->statement._config.option = option;
58       a->statement._config.a = value;
59       a->statement._config.e = NULL;
60       log_msg(ast_log_level, "ast: new attribute option statement (%p): option: %d, value: %p", a, option, value);
61       return a;
62 }
63 
new_include_statement(string_expression * path,string_expression * rx,bool execute)64 ast* new_include_statement(string_expression* path, string_expression* rx, bool execute) {
65       ast* a = new_ast_node();
66 
67       a->type = include_statement_type;
68       a->statement._include.path = path;
69       a->statement._include.rx = rx;
70       a->statement._include.execute = execute;
71 
72       log_msg(ast_log_level, "ast: new include statement (%p): path: %p, rx: %p, execute: %s", a, path, rx, btoa(execute));
73       return a;
74 }
75 
new_x_include_setenv_statement(char * variable,string_expression * value)76 ast* new_x_include_setenv_statement(char *variable, string_expression *value) {
77       ast* a = new_ast_node();
78 
79       a->type = x_include_setenv_statement_type;
80       a->statement._x_include_setenv.variable = variable;
81       a->statement._x_include_setenv.value = value;
82       log_msg(ast_log_level, "ast: new x_include_setenv statement (%p): variable: '%s', value: %p", a, variable, value);
83       return a;
84 }
85 
new_define_statement(char * name,string_expression * value)86 ast* new_define_statement(char *name, string_expression *value) {
87       ast* a = new_ast_node();
88 
89       a->type = define_statement_type;
90       a->statement._define.name = name;
91       a->statement._define.value = value;
92       log_msg(ast_log_level, "ast: new define statement (%p): name: '%s', value: %p", a, name, value);
93       return a;
94 }
95 
new_undefine_statement(char * name)96 ast* new_undefine_statement(char *name) {
97       ast* a = new_ast_node();
98 
99       a->type = undefine_statement_type;
100       a->statement._undefine.name = name;
101       log_msg(ast_log_level, "ast: new undefine statement (%p): name: '%s'", a, name);
102       return a;
103 }
104 
new_group_statement(char * name,attribute_expression * expr)105 ast* new_group_statement(char* name, attribute_expression* expr) {
106       ast* a = new_ast_node();
107 
108       a->type = group_statement_type;
109       a->statement._group.name = name;
110       a->statement._group.expr = expr;
111       log_msg(ast_log_level, "ast: new group statement (%p): name: '%s', expr: %p", a, name, expr);
112       return a;
113 }
114 
new_string_bool_expression(bool_operator op,string_expression * expr)115 bool_expression* new_string_bool_expression(bool_operator op, string_expression* expr) {
116     bool_expression* e = checked_malloc(sizeof(bool_expression));
117     e->op = op;
118     e->expr = expr;
119     e->left = NULL;
120     e->right = NULL;
121     log_msg(ast_log_level, "ast: new bool expression (%p): op: %d, expr: %p", e, op, expr);
122     return e;
123 }
124 
new_bool_expression(bool_operator op,bool_expression * left,bool_expression * right)125 bool_expression* new_bool_expression(bool_operator op, bool_expression* left, bool_expression* right) {
126     bool_expression* e = checked_malloc(sizeof(bool_expression));
127     e->op = op;
128     e->expr = NULL;
129     e->left = left;
130     e->right = right;
131     log_msg(ast_log_level, "ast: new bool expression (%p): op: %d, left: %p, right: %p", e, op, left, right);
132     return e;
133 }
134 
new_if_condition(bool_expression * expression)135 if_condition* new_if_condition(bool_expression* expression) {
136     if_condition* c = checked_malloc(sizeof(if_condition));
137 
138     c->linenumber = conf_linenumber;
139     c->filename = conf_filename;
140     c->linebuf = conf_linebuf;
141 
142     c->expression = expression;
143 
144     log_msg(ast_log_level, "ast: if condition (%p): expression: %p", c,  expression);
145     return c;
146 }
147 
new_attribute_expression(attribute_operator op,attribute_expression * left,char * right)148 attribute_expression* new_attribute_expression(attribute_operator op, attribute_expression* left, char* right) {
149     attribute_expression* e = checked_malloc(sizeof(attribute_expression));
150     e->op = op;
151     e->left = left;
152     e->right = right;
153     log_msg(ast_log_level, "ast: new attribute expression (%p): op: %d, left: %p, right: '%s'", e, op, left, right);
154     return e;
155 }
156 
new_restriction_expression(restriction_expression * left,char * right)157 restriction_expression* new_restriction_expression(restriction_expression* left, char* right) {
158     restriction_expression* e = checked_malloc(sizeof(restriction_expression));
159     e->right = right;
160     e->left = left;
161     log_msg(ast_log_level, "ast: new restriction expression (%p): left: %p, right: '%s'", e, left, right);
162     return e;
163 }
164 
new_if_statement(struct if_condition * condition,struct ast * if_branch,struct ast * else_branch)165 ast* new_if_statement(struct if_condition* condition, struct ast* if_branch, struct ast* else_branch) {
166       ast* e = new_ast_node();
167 
168       e->type = if_statement_type;
169       e->statement._if.condition = condition;
170       e->statement._if.if_branch = if_branch;
171       e->statement._if.else_branch = else_branch;
172       log_msg(ast_log_level, "ast: new if statement (%p): condition: %p, if_branch: %p, else_branch: %p", e, condition, if_branch, else_branch);
173       return e;
174 }
175 
new_rule_statement(AIDE_RULE_TYPE rule_type,string_expression * path,restriction_expression * restriction,attribute_expression * attrs)176 ast* new_rule_statement(AIDE_RULE_TYPE rule_type, string_expression* path, restriction_expression* restriction, attribute_expression* attrs) {
177       ast* e = new_ast_node();
178 
179       e->type = rule_statement_type;
180       e->statement._rule.type = rule_type;
181       e->statement._rule.path = path;
182       e->statement._rule.restriction = restriction;
183       e->statement._rule.attributes = attrs;
184       log_msg(ast_log_level, "ast: new rule statement (%p): type: %s, path: %p, restriction: %p, attributes: %p", e, get_rule_type_long_string(rule_type), path, restriction, attrs);
185       return e;
186 }
187 
new_string(char * str)188 string_expression* new_string(char *str) {
189     string_expression* e = checked_malloc(sizeof(string_expression));
190 
191     e->op = STR_OP_STR;
192     e->str = str;
193     e->left = NULL;
194     e->right = NULL;
195     log_msg(ast_log_level, "ast: new string (%p): str: '%s'", e, str);
196     return e;
197 }
new_variable(char * name)198 string_expression* new_variable(char *name) {
199     string_expression* e = checked_malloc(sizeof(string_expression));
200 
201     e->op = STR_OP_VARIABLE;
202     e->str = name;
203     e->left = NULL;
204     e->right = NULL;
205     log_msg(ast_log_level, "ast: new variable (%p): name: '%s'", e, name);
206     return e;
207 }
new_string_concat(string_expression * left,string_expression * right)208 string_expression* new_string_concat(string_expression* left, string_expression* right) {
209     string_expression* e = checked_malloc(sizeof(string_expression));
210     e->op = STR_OP_CONCAT;
211     e->str = NULL;
212     e->left = left;
213     e->right = right;
214     log_msg(ast_log_level, "ast: new string concat (%p): left: %p, right: %p", e, left, right);
215     return e;
216 }
217 
free_string(char * s)218 void free_string(char * s) {
219     if (s == NULL) {
220         return;
221     }
222     log_msg(ast_log_level, "ast: free string %p", s);
223     free(s);
224 }
225 
free_attribute_expression(attribute_expression * a)226 void free_attribute_expression(attribute_expression *a) {
227     if (a == NULL) {
228         return;
229     }
230     free_attribute_expression(a->left);
231     free_string(a->right);
232     log_msg(ast_log_level, "ast: free attribute expression %p", a);
233     free(a);
234 }
235 
free_string_expression(string_expression * s)236 void free_string_expression(string_expression *s) {
237     if (s == NULL) {
238         return;
239     }
240     free_string_expression(s->left);
241     free_string_expression(s->right);
242     free_string(s->str);
243     log_msg(ast_log_level, "ast: free string expression %p", s);
244     free(s);
245 }
246 
free_bool_expression(bool_expression * b)247 void free_bool_expression(bool_expression *b) {
248     if (b == NULL) {
249         return;
250     }
251     free_string_expression(b->expr);
252     free_bool_expression(b->left);
253     free_bool_expression(b->right);
254     log_msg(ast_log_level, "ast: free bool expression %p", b);
255     free(b);
256 }
257 
free_if_condition(if_condition * c)258 void free_if_condition(if_condition *c) {
259     free_bool_expression(c->expression);
260     free_string(c->linebuf);
261     log_msg(ast_log_level, "ast: free if condition %p", c);
262     free(c);
263 }
264 
free_restriction_expression(restriction_expression * r)265 void free_restriction_expression(restriction_expression *r) {
266     if (r == NULL) {
267         return;
268     }
269     free_restriction_expression(r->left);
270     free_string(r->right);
271     log_msg(ast_log_level, "ast: free restriction expression %p", r);
272     free(r);
273 }
274 
deep_free(ast * config_ast)275 void deep_free(ast* config_ast) {
276     if (config_ast == NULL) {
277         return;
278     }
279     ast* node = NULL;
280     for(node = config_ast; node != NULL; ) {
281         switch (node->type) {
282             case config_option_type:
283                 free_attribute_expression(node->statement._config.a);
284                 free_string_expression(node->statement._config.e);
285                 break;
286             case define_statement_type:
287                 free_string_expression(node->statement._define.value);
288                 free_string(node->statement._define.name);
289                 break;
290             case group_statement_type:
291                 free_attribute_expression(node->statement._group.expr);
292                 free_string(node->statement._group.name);
293                 break;
294             case if_statement_type:
295                 free_if_condition(node->statement._if.condition);
296                 deep_free(node->statement._if.if_branch);
297                 deep_free(node->statement._if.else_branch);
298                 break;
299             case include_statement_type:
300                 free_string_expression(node->statement._include.path);
301                 free_string_expression(node->statement._include.rx);
302                 break;
303             case x_include_setenv_statement_type:
304                 free_string_expression(node->statement._x_include_setenv.value);
305                 free_string(node->statement._x_include_setenv.variable);
306                 break;
307             case rule_statement_type:
308                 free_string_expression(node->statement._rule.path);
309                 free_restriction_expression(node->statement._rule.restriction);
310                 free_attribute_expression(node->statement._rule.attributes);
311                 break;
312             case undefine_statement_type:
313                 free_string(node->statement._define.name);
314                 break;
315         }
316         free(node->linebuf);
317         ast* to_be_freed = node;
318         node = node->next;
319         log_msg(ast_log_level, "ast: free ast node %p (next: %p)", to_be_freed, node);
320         free(to_be_freed);
321     }
322 }
323