1 C [^\n\t ]
2
3 L [a-zA-Z���������0-9_%]
4 G [a-zA-Z0-9]
5 V [a-zA-Z_]+[a-zA-Z0-9_]*
6 E [\ ]*"="[\ ]*
7
8 %{
9
10 #define YYDEBUG 1
11
12 /*
13 * AIDE (Advanced Intrusion Detection Environment)
14 *
15 * Copyright (C) 1999-2002, 2004-2006, 2010-2013, 2015-2016, 2019-2021
16 * Rami Lehti, Pablo Virolainen, Richard van den Berg,
17 * Hannes von Haugwitz
18 *
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License as
21 * published by the Free Software Foundation; either version 2 of the
22 * License, or (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful, but
25 * WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 */
33
34 #include "aide.h"
35 #include <string.h>
36 #include <stdlib.h>
37 #include "gen_list.h"
38 #include "util.h"
ThreadParamsbase::__anonb666fa2f0111::ThreadParams39 #include "conf_yacc.h"
40 #include "list.h"
41 #include "errorcodes.h"
42 #include "symboltable.h"
43 #include "commandconf.h"
44
45 #include "conf_ast.h"
46
47 #define LOG_LEX_TOKEN(log_level, token, text) \
48 log_msg(log_level, "%s:%d: \u2502 " #token " (text: '%s')", conf_filename, conf_linenumber, text);
49
50 #define LOG_CONFIG_LINE(log_level, msg) \
51 log_msg(log_level, "%s:%d: %s (line: '%s')", conf_filename, conf_linenumber, msg, conf_linebuf);
52
53 #define DEPRECATION_WARNING(deprecated_option, new_option) \
54 log_msg(LOG_LEVEL_WARNING, "%s:%d: Using '%s' is DEPRECATED. Update your config and use '%s' instead (line: '%s')", conf_filename, conf_linenumber, deprecated_option, new_option ,conf_linebuf); \
55
56 int conf_linenumber = 0;
57 char *conf_filename;
58 char *conf_linebuf;
59
60 LOG_LEVEL lex_log_level = LOG_LEVEL_CONFIG;
61
62 #define YY_INPUT(buf,result,max_size) \
63 if( ((result=conf_input_wrapper(buf,max_size,confin)) == 0) \
64 && ferror(yyin) ) \
65 YY_FATAL_ERROR( "input in flex scanner failed" );
66
67 %}
68
69 %option noinput nounput
70
71 %x CONFIG DEFSTMT ENVVAR EXPR EXPREQUHUNT PATH STRING STRINGS STRINGEQHUNT STRINGHUNT
72
73 %%
74 <INITIAL>^[\t\ ]*"#"[^\n]*"\n" {
75 conf_linebuf = checked_strndup(conftext, confleng-1);
76 ++conf_linenumber;
CreateThread(size_t stack_size,bool joinable,PlatformThread::Delegate * delegate,PlatformThreadHandle * thread_handle,ThreadPriority priority)77 LOG_CONFIG_LINE(lex_log_level, "- skip comment line")
78 free(conf_linebuf);
79 }
80 <INITIAL>^[\t\ ]*"\n" {
81 conf_linebuf = "";
82 ++conf_linenumber;
83 LOG_CONFIG_LINE(lex_log_level, "- skip empty line")
84 }
85 <INITIAL>^[^\n]* {
86 conf_linebuf = checked_strndup(conftext, confleng);
87 ++conf_linenumber;
88 log_msg(lex_log_level,"%s:%d: \u252c '%s'", conf_filename, conf_linenumber, conf_linebuf);
89 yyless(0);
90 BEGIN(CONFIG);
91 }
92 <CONFIG>"#"[^\n]* { /* inline comment */
93 LOG_LEX_TOKEN(lex_log_level, skip inline comment, conftext)
94 }
95
96 <CONFIG>"=/" {
97 LOG_LEX_TOKEN(lex_log_level, TEQURXRULE, "=")
98 yyless(strchr(conftext,'/')-conftext);
99 BEGIN(PATH);
100 return (TEQURXRULE);
101 }
102
103 <CONFIG>"/" {
104 LOG_LEX_TOKEN(lex_log_level, TSELRXRULE, "")
105 yyless(strchr(conftext,'/')-conftext);
106 BEGIN(PATH);
107 return (TSELRXRULE);
108 }
109
110 <CONFIG>"!/" {
111 LOG_LEX_TOKEN(lex_log_level, TNEGRXRULE, "!")
112 yyless(strchr(conftext,'/')-conftext);
113 BEGIN(PATH);
114 return (TNEGRXRULE);
115 }
116
117 <EXPREQUHUNT>{E} {
118 LOG_LEX_TOKEN(lex_log_level, '=', conftext)
119 BEGIN(EXPR);
120 return('=');
121 }
122
123 <EXPR>({L}|">")+ {
124 LOG_LEX_TOKEN(lex_log_level, TEXPR, conftext)
125 conflval.s=checked_strdup(conftext);
126 return (TEXPR);
CurrentId()127 }
128
129 <EXPR>\+ { /* attribute operator */
130 LOG_LEX_TOKEN(lex_log_level, '+', conftext)
131 return ('+');
132 }
133
134 <EXPR>\- { /* attribute operator */
135 LOG_LEX_TOKEN(lex_log_level, '-', conftext)
136 return ('-');
137 }
138
139 <EXPR>, { /* restriction seperator */
140 LOG_LEX_TOKEN(lex_log_level, ',', conftext)
141 return (',');
142 }
143
144 <DEFSTMT>({L})+ {
145 LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conftext)
146 conflval.s=checked_strdup(conftext);
147 BEGIN(STRINGHUNT);
148 return (TVARIABLE);
CurrentRef()149 }
150
151 <CONFIG>"\@\@define" {
152 LOG_LEX_TOKEN(lex_log_level, TDEFINE, conftext)
153 BEGIN DEFSTMT;
154 return (TDEFINE);
155 }
156
157 <CONFIG>"\@\@undef" {
158 LOG_LEX_TOKEN(lex_log_level, TUNDEFINE, conftext)
YieldCurrentThread()159 BEGIN DEFSTMT;
160 return (TUNDEFINE);
161 }
162
163 <CONFIG>"\@\@ifdef" {
Sleep(TimeDelta duration)164 LOG_LEX_TOKEN(lex_log_level, TIFDEF, conftext)
165 BEGIN(STRINGHUNT);
166 return (TIFDEF);
167 }
168
169 <CONFIG>"\@\@ifndef" {
170 LOG_LEX_TOKEN(lex_log_level, TIFNDEF, conftext)
171 BEGIN(STRINGHUNT);
172 return (TIFNDEF);
173 }
174
175 <CONFIG>"\@\@else" {
176 LOG_LEX_TOKEN(lex_log_level, TELSE, conftext)
177 BEGIN CONFIG;
178 return (TELSE);
GetName()179 }
180
181 <CONFIG>"\@\@endif" {
182 LOG_LEX_TOKEN(lex_log_level, TENDIF, conftext)
183 BEGIN CONFIG;
184 return (TENDIF);
185 }
186
187 <CONFIG>"\@\@ifhost" {
188 LOG_LEX_TOKEN(lex_log_level, TIFHOST, conftext)
189 BEGIN(STRINGHUNT);
190 return (TIFHOST);
191 }
CreateNonJoinable(size_t stack_size,Delegate * delegate)192
193 <CONFIG>"\@\@ifnhost" {
194 LOG_LEX_TOKEN(lex_log_level, TIFNHOST, conftext)
195 BEGIN(STRINGHUNT);
196 return (TIFNHOST);
197 }
198
199 <CONFIG>"\@\@include" {
200 LOG_LEX_TOKEN(lex_log_level, TINCLUDE, conftext)
Join(PlatformThreadHandle thread_handle)201 BEGIN(STRINGS);
202 return (TINCLUDE);
203 }
204
205 <CONFIG>"\@\@x_include" {
206 LOG_LEX_TOKEN(lex_log_level, TXINCLUDE, conftext)
207 BEGIN(STRINGS);
208 return (TXINCLUDE);
209 }
210
211 <CONFIG>"\@\@x_include_setenv" {
212 LOG_LEX_TOKEN(lex_log_level, TSETENV, conftext)
SetCurrentThreadPriority(ThreadPriority priority)213 BEGIN ENVVAR;
214 return (TSETENV);
215 }
216
217 <ENVVAR>({V})+ {
218 LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conftext)
219 conflval.s=checked_strdup(conftext);
220 BEGIN(STRINGHUNT);
221 return (TVARIABLE);
222 }
223
224 <CONFIG,DEFSTMT,ENVVAR,EXPR>[\t\ ]+ {
225 LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
226 }
227
228 <CONFIG>"database_in" {
229 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_IN_OPTION), conftext)
230 conflval.option = DATABASE_IN_OPTION;
231 BEGIN (STRINGEQHUNT);
232 return (CONFIGOPTION);
233 }
234
GetCurrentThreadPriority()235 <CONFIG>"database" {
236 DEPRECATION_WARNING("database", "database_in")
237 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_IN_OPTION), conftext)
238 conflval.option = DATABASE_IN_OPTION;
239 BEGIN (STRINGEQHUNT);
240 return (CONFIGOPTION);
241 }
242
243 <CONFIG>"database_out" {
244 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_OUT_OPTION), conftext)
245 conflval.option = DATABASE_OUT_OPTION;
246 BEGIN (STRINGEQHUNT);
247 return (CONFIGOPTION);
248 }
249
250 <CONFIG>"database_new" {
251 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_NEW_OPTION), conftext)
252 conflval.option = DATABASE_NEW_OPTION;
253 BEGIN (STRINGEQHUNT);
254 return (CONFIGOPTION);
255 }
256
257 <CONFIG>"database_attrs" {
258 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_ATTRIBUTES_OPTION), conftext)
259 conflval.option = DATABASE_ATTRIBUTES_OPTION;
260 BEGIN (EXPREQUHUNT);
261 return (CONFIGOPTION);
262 }
263
264 <CONFIG>"warn_dead_symlinks" {
265 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (WARN_DEAD_SYMLINKS_OPTION), conftext)
266 conflval.option = WARN_DEAD_SYMLINKS_OPTION;
267 BEGIN (STRINGEQHUNT);
268 return (CONFIGOPTION);
269 }
270
271 <CONFIG>"grouped" {
272 DEPRECATION_WARNING("grouped", "report_grouped")
273 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_GROUPED_OPTION), conftext)
274 conflval.option = REPORT_GROUPED_OPTION;
275 BEGIN (STRINGEQHUNT);
276 return (CONFIGOPTION);
277 }
278
279 <CONFIG>"report_grouped" {
280 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_GROUPED_OPTION), conftext)
281 conflval.option = REPORT_GROUPED_OPTION;
282 BEGIN (STRINGEQHUNT);
283 return (CONFIGOPTION);
284 }
285
286 <CONFIG>"summarize_changes" {
287 DEPRECATION_WARNING("summarize_changes", "report_summarize_changes")
288 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_SUMMARIZE_CHANGES_OPTION), conftext)
289 conflval.option = REPORT_SUMMARIZE_CHANGES_OPTION;
290 BEGIN (STRINGEQHUNT);
291 return (CONFIGOPTION);
292 }
293
294 <CONFIG>"report_summarize_changes" {
295 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_SUMMARIZE_CHANGES_OPTION), conftext)
296 conflval.option = REPORT_SUMMARIZE_CHANGES_OPTION;
297 BEGIN (STRINGEQHUNT);
298 return (CONFIGOPTION);
299 }
300 <CONFIG>"acl_no_symlink_follow" {
301 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (ACL_NO_SYMLINK_FOLLOW_OPTION), conftext)
302 conflval.option = ACL_NO_SYMLINK_FOLLOW_OPTION;
303 BEGIN (STRINGEQHUNT);
304 return (CONFIGOPTION);
305 }
306
307 <CONFIG>"report_level" {
308 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_LEVEL_OPTION), conftext)
309 conflval.option = REPORT_LEVEL_OPTION;
310 BEGIN (STRINGEQHUNT);
311 return (CONFIGOPTION);
312 }
313
314 <CONFIG>"report_ignore_added_attrs" {
315 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_ADDED_ATTRS_OPTION), conftext)
316 conflval.option = REPORT_IGNORE_ADDED_ATTRS_OPTION;
317 BEGIN (EXPREQUHUNT);
318 return (CONFIGOPTION);
319 }
320
321 <CONFIG>"report_ignore_removed_attrs" {
322 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_REMOVED_ATTRS_OPTION), conftext)
323 conflval.option = REPORT_IGNORE_REMOVED_ATTRS_OPTION;
324 BEGIN (EXPREQUHUNT);
325 return (CONFIGOPTION);
326 }
327
328 <CONFIG>"report_ignore_changed_attrs" {
329 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_CHANGED_ATTRS_OPTION), conftext)
330 conflval.option = REPORT_IGNORE_CHANGED_ATTRS_OPTION;
331 BEGIN (EXPREQUHUNT);
332 return (CONFIGOPTION);
333 }
334
335 <CONFIG>"report_force_attrs" {
336 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_FORCE_ATTRS_OPTION), conftext)
337 conflval.option = REPORT_FORCE_ATTRS_OPTION;
338 BEGIN (EXPREQUHUNT);
339 return (CONFIGOPTION);
340 }
341
342 <CONFIG>"verbose" {
343 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (VERBOSE_OPTION), conftext)
344 conflval.option = VERBOSE_OPTION;
345 BEGIN (STRINGEQHUNT);
346 return (CONFIGOPTION);
347 }
348
349 <CONFIG>"log_level" {
350 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (LOG_LEVEL_OPTION), conftext)
351 conflval.option = LOG_LEVEL_OPTION;
352 BEGIN(STRINGEQHUNT);
353 return (CONFIGOPTION);
354 }
355
356 <CONFIG>"database_add_metadata" {
357 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_ADD_METADATA_OPTION), conftext)
358 conflval.option = DATABASE_ADD_METADATA_OPTION;
359 BEGIN (STRINGEQHUNT);
360 return (CONFIGOPTION);
361 }
362
363 <CONFIG>"report_url" {
364 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_URL_OPTION), conftext)
365 conflval.option = REPORT_URL_OPTION;
366 BEGIN (STRINGEQHUNT);
367 return (CONFIGOPTION);
368 }
369
370 <CONFIG>"report_detailed_init" {
371 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_DETAILED_INIT_OPTION), conftext)
372 conflval.option = REPORT_DETAILED_INIT_OPTION;
373 BEGIN (STRINGEQHUNT);
374 return (CONFIGOPTION);
375 }
376
377 <CONFIG>"report_base16" {
378 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_BASE16_OPTION), conftext)
379 conflval.option = REPORT_BASE16_OPTION;
380 BEGIN (STRINGEQHUNT);
381 return (CONFIGOPTION);
382 }
383
384 <CONFIG>"report_quiet" {
385 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_QUIET_OPTION), conftext)
386 conflval.option = REPORT_QUIET_OPTION;
387 BEGIN (STRINGEQHUNT);
388 return (CONFIGOPTION);
389 }
390
391 <CONFIG>"report_append" {
392 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_APPEND_OPTION), conftext)
393 conflval.option = REPORT_APPEND_OPTION;
394 BEGIN (STRINGEQHUNT);
395 return (CONFIGOPTION);
396 }
397
398 <CONFIG>"report_ignore_e2fsattrs" {
399 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_E2FSATTRS_OPTION), conftext)
400 conflval.option = REPORT_IGNORE_E2FSATTRS_OPTION;
401 BEGIN (STRINGEQHUNT);
402 return (CONFIGOPTION);
403 }
404
405 <CONFIG>"gzip_dbout" {
406 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_GZIP_OPTION), conftext)
407 conflval.option = DATABASE_GZIP_OPTION;
408 BEGIN (STRINGEQHUNT);
409 return (CONFIGOPTION);
410 }
411
412 <CONFIG>"root_prefix" {
413 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (ROOT_PREFIX_OPTION), conftext)
414 conflval.option = ROOT_PREFIX_OPTION;
415 BEGIN (STRINGEQHUNT);
416 return (CONFIGOPTION);
417 }
418
419 <CONFIG>"config_version" {
420 LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (CONFIG_VERSION), conftext)
421 conflval.option = CONFIG_VERSION;
422 BEGIN (STRINGEQHUNT);
423 return (CONFIGOPTION);
424 }
425
426 <CONFIG>({G})+ { /* group definition */
427 conflval.s=checked_strdup(conftext);
428 LOG_LEX_TOKEN(lex_log_level, TGROUP, conftext)
429 BEGIN(EXPREQUHUNT);
430 return (TGROUP);
431 }
432
433 <CONFIG>({L})+ { /* group definition, deprecated group names */
434 log_msg(LOG_LEVEL_WARNING, "%s:%d: special characters in group names are DEPRECATED. Update your config and only use alphanumeric characters (A-Za-z0-9) (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); \
435 conflval.s=checked_strdup(conftext);
436 LOG_LEX_TOKEN(lex_log_level, TGROUP, conftext)
437 BEGIN(EXPREQUHUNT);
438 return (TGROUP);
439 }
440
441 <STRINGEQHUNT>{E} {
442 LOG_LEX_TOKEN(lex_log_level, '=', conftext)
443 BEGIN(STRING);
444 return('=');
445 }
446
447 <STRINGS,STRING,PATH>"@@{"({L}+)"}" {
448 size_t length = strlen(conftext)-4;
449 conflval.s=checked_malloc(length+1);
450 strncpy(conflval.s, conftext+3, length);
451 conflval.s[length] = '\0';
452 LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conflval.s)
453 return (TVARIABLE);
454 }
455
456 <STRINGS,STRING,PATH>[^@\\ \t\n]+ {
457 LOG_LEX_TOKEN(lex_log_level, TSTRING, conftext)
458 conflval.s=checked_strdup(conftext);
459 return (TSTRING);
460 }
461
462 <STRINGS,STRING,PATH>\\[\\@ ] {
463 LOG_LEX_TOKEN(lex_log_level, (escaped) TSTRING, conftext)
464 conflval.s=checked_strdup(conftext+1);
465 return (TSTRING);
466 }
467
468 <STRINGS,STRING,PATH>[\\@] {
469 LOG_LEX_TOKEN(lex_log_level, (single-character) TSTRING, conftext)
470 conflval.s=checked_strdup(conftext);
471 return (TSTRING);
472 }
473
474 <STRINGS>[\ \t]+ {
475 LOG_LEX_TOKEN(lex_log_level, TSPACE, conftext)
476 return (TSPACE);
477 }
478
479 <STRING>[\ \t]+ {
480 LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
481 BEGIN(CONFIG);
482 }
483
484 <PATH>[\ \t]+ {
485 LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
486 BEGIN(EXPR);
487 }
488
489 <STRINGHUNT>[\ \t]+ {
490 LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext)
491 BEGIN(STRING);
492 }
493
494 <STRINGHUNT>[^\ \t\n] {
495 LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, found string -> unput, conftext)
496 yyless(0);
497 BEGIN(STRING);
498 }
499
500 <CONFIG,DEFSTMT,ENVVAR,EXPR,EXPREQUHUNT,PATH,STRINGS,STRING,STRINGEQHUNT,STRINGHUNT>[\t\ ]*"\n" {
501 log_msg(lex_log_level,"%s:%d: \u2534 TNEWLINE (text: '\\n')", conf_filename, conf_linenumber);
502 BEGIN 0;
503 return (TNEWLINE);
504 }
505
506 <*>. {
507 log_msg(LOG_LEVEL_ERROR,"%s:%d: unexpected character: '%c' (line: '%s')", conf_filename, conf_linenumber, *conftext, conf_linebuf);
508 exit(INVALID_CONFIGURELINE_ERROR);
509 }
510
511 %%
512
513 int confwrap(void){
514 return 1;
515 }
516
517 void conf_lex_string(const char * name, const char *string) {
518 log_msg(LOG_LEVEL_DEBUG, "parse: '%s'", name);
519 conf_linenumber = 0;
520 conf_filename = checked_strdup(name); /* not to be freed, needed for logging */
521 conf_scan_string(string);
522 }
523
524 void conf_lex_file(const char * config) {
525 log_msg(LOG_LEVEL_DEBUG, "parse: '%s'", config);
526 conf_linenumber = 0;
527
528 if (strcmp(config,"-") == 0) {
529 conf_filename = checked_strdup("(stdin)"); /* not to be freed, needed for logging */
530 confin = stdin;
531 } else {
532 conf_filename = checked_strdup(config); /* not to be freed, needed for logging */
533 char *expanded_config = expand_tilde(checked_strdup(config));
534 confin = fopen( expanded_config, "r" );
535 if (!confin) {
536 log_msg(LOG_LEVEL_ERROR,"cannot open config file '%s': %s", config, strerror(errno));
537 exit(IO_ERROR);
538 }
539 free(expanded_config);
540 expanded_config=NULL;
541 }
542 conf_switch_to_buffer(conf_create_buffer( confin, YY_BUF_SIZE ));
543 }
544
545 void conf_lex_delete_buffer() {
546 conf_delete_buffer( YY_CURRENT_BUFFER );
547 }
548