aide-0.19.3/0000755000175000017500000000000015137355021013732 5ustar00hvhaugwitzhvhaugwitzaide-0.19.3/ChangeLog0000644000175000017500000021661015137354765015530 0ustar00hvhaugwitzhvhaugwitz2026-01-31 Hannes von Haugwitz * Release aide 0.19.3 2025-12-26 Hannes von Haugwitz * Fix st_rdev handling (closes: #208) 2025-09-03 Attila Lakatos * Fix typos in README, NEWS and aide.conf.5 2025-08-13 Hannes von Haugwitz * Release aide 0.19.2 2025-08-07 Hannes von Haugwitz * Escape control characters in report and log output (CVE-2025-54389), thanks to Rajesh Pangare for reporting this issue * Fix null pointer dereference after reading incorrectly encoded xattr attributes from database (CVE-2025-54409) - fix handling of empty xattr values - fix handling of xattr keys containing a comma - thanks to Rajesh Pangare for reporting this issue 2025-07-06 Hannes von Haugwitz * Release aide 0.19.1 2025-07-03 Hannes von Haugwitz * Fix race condition when adding new nodes during file system scan 2025-05-01 Hannes von Haugwitz * Extend expiration dates of GPG key in SECURITY.md 2025-04-20 Hannes von Haugwitz * Define MAGIC constants added since Linux 4.9 (closes: #192) 2025-04-05 Hannes von Haugwitz * Fix build with additional libraries on non-Linux systems * Update NEWS file and aide.conf.5 man page * Move log message to limit log level * Release aide 0.19 2025-03-29 Hannes von Haugwitz * Add log level 'limit' * Fix performance calculation when using --limit 2025-03-28 Hannes von Haugwitz * Fix display of some URLs (closes: #183) 2025-03-25 Hannes von Haugwitz * Handle SIGUSR1 only after config parsing (closes: #181) * Require nettle >= 3.7 and libselinux >= 3.4 2025-03-23 Hannes von Haugwitz * Fix parsing of invalid time values * Fix locking of wrong node * Fix writing of negative time values * Fix listing of attributes * Improve logging * Fix missing parent directory in path check output 2025-03-22 Hannes von Haugwitz * Remove no longer needed caching code * Fix deadlock when using some special attributes 2025-03-16 Hannes von Haugwitz * Open files for reading only after rule tree matching * Fix compilation when O_PATH is not defined 2025-03-10 Hannes von Haugwitz * Add 'version_ge' boolean operator (closes: #83) 2025-03-09 Hannes von Haugwitz * Use O_NONBLOCK when opening files * Add AIDE_VERSION macro variable 2025-03-07 Hannes von Haugwitz * Escape further special characters in JSON strings (closes: #189) 2025-03-02 Hannes von Haugwitz * Minor code improvements and code cleanup * Properly close file descriptors of included config files * Improve some logging 2025-03-01 Hannes von Haugwitz * Add support for file system type restricted rules (Linux only) - add 'fstype' attribute - add '--without-fstype' configure option - closes: #39 2025-02-23 Hannes von Haugwitz * Fix omission of file type in database report section 2025-02-22 Hannes von Haugwitz * Apply rules only to file system entries and no longer to database entries * Fix available hashsums in --version output when using libgcrypt (closes: #187) * Fix display of unknown file type in detailed report section 2025-02-22 yixiangzhike * Remove deprecated hashsums from default config option database_attrs 2025-01-13 Hannes von Haugwitz * Fix calculation of duration 2025-01-12 Hannes von Haugwitz * Refactor file processing code - operate on file descriptor (opened once) - significantly reduce "file has changed" warnings - warn about file change after hash calculation - disable attributes if not supported by file type - improve error handling - improve logging 2025-01-02 Hannes von Haugwitz * Add missing suffix to decimal constants 2025-01-01 Hannes von Haugwitz * Fix entries per second calculation for logging * Limit Linux capabilities to regular files 2024-11-23 Hannes von Haugwitz * Refactor code to prepare for file system type restrictions * move failed JIT compilation log message to DEBUG level 2024-11-10 Hannes von Haugwitz * Remove deprecated hashsums from H default group (closes: #179) 2024-10-14 Hannes von Haugwitz * Update aide.conf man page 2024-10-13 Hannes von Haugwitz * Refactor input database code - use strtok_r instead of flex for tokenizing - support integer and base64 representation for time_t * Refactor output database code - save time_t as integer instead of base64 encoded string 2024-09-03 Hannes von Haugwitz * Fix parsing of lowercase group names (closes: #176) 2024-07-15 Hannes von Haugwitz * Switch from libmhash to libnettle (closes: #150, #164) - add 'sha512_256', sha3_256, and 'sha3_512' hashsums - switch hashsum in R default group from md5 to sha3_256 - deprecate legacy hashsums (md5, sha1, rmd160, gost) - remove unsupported hashsums (haval, crc32, crc32b, tiger, whirlpool) - add limited support for hashsum transitions - add check_hashsum unit test 2024-07-11 Zopolis4 * Set autogen.sh and version.sh as executable 2024-07-08 Marc 'Zugschlus' Haber * Allow version.sh to accept GIT_VERSION from environment 2024-06-16 Hannes von Haugwitz * Add non-recursive negative rules (-) - change semantic of unrestricted (recursive) negative rules - refactor rule matching code - improve output for --path-check and --dry-run - improve file tree processing when using limit * Specify PCRE2 variant in README * Fix typo in macro name * Clean up #include statements * Don't use glib specific TEMP_FAILURE_RETRY macro 2024-06-15 Walter Doekes * Fix escacped typo * Fix JSON escaping of filenames in different_attributes 2024-05-30 Michael Ruigrok * Fix grammar of a/an in aide.conf.5 2024-05-08 Hannes von Haugwitz * Fix concurrent reading of extended attributes (xattrs) 2024-05-05 Hannes von Haugwitz * Raise warning if both input databases are the same * Fix progress bar to show skipped entries for database_new 2024-04-27 Hannes von Haugwitz * Refactor progress bar code * Add check_progress unit test * Add missing library CFLAGS * Add basic check_base64 unit test * Remove unused length_base64 function * Remove AM_CFLAGS/AM_CPPFLAGS variables 2024-04-21 Hannes von Haugwitz * Add check_seltree unit test 2024-04-20 Hannes von Haugwitz * Fix compiler warnings * Fix 64-bit time_t on 32-bit architectures * Fix typo in aide.conf manual page (closes: #165) 2024-01-17 Hannes von Haugwitz * Fix debug logging for returned attributes 2024-01-14 Hannes von Haugwitz * Code cleanup and log improvements 2024-01-13 Hannes von Haugwitz * Code cleanup (remove strip_dbline function) 2024-01-02 Hannes von Haugwitz * Add missing command and option to --help output 2023-12-31 Hannes von Haugwitz * Only remove incompletely written db file if it was created by aide * Show number of skipped files on progress bar 2023-12-29 Hannes von Haugwitz * Improve logging - move COMPARE log level before RULE log level - remove redundant log messages - move some log messages from lower to upper log levels - improve locking 2023-12-19 Hannes von Haugwitz * Refactor signal handling (closes: #147) - do not ignore SIGHUP and SIGTERM signals - remove incompletely written database and exit on SIGHUP, SIGTERM or SIGINT - add exit code 25 for signal interruptions - Update SIGNAL HANDLING section of aide.1 manual page * Fix compiler warnings for printf style functions * Add colors to log output (add '--no-color' parameter) 2023-12-04 Hannes von Haugwitz * Handle an incompletely written input database as an error 2023-12-03 Hannes von Haugwitz * Add '--list' command to list the entries of the database in human-readable format (closes: #9) 2023-11-18 Hannes von Haugwitz * Fix format function attribute for some printf style functions * Fix several compiler warnings for printf style functions (closes: #162), thanks to Mingjie Shen for the initial patch 2023-11-17 Mingjie Shen * Fix condition for error message of failing to open gzipped files 2023-07-30 Hannes von Haugwitz * Remove deprecated config options - 'database' (replaced by 'database_in') - 'summarize_changes' (replaced by 'report_summarize_changes') - 'grouped' (replaced by 'report_grouped') * Remove handling of outdated config parameters/option * Raise log level for some deprecations 2023-07-22 Hannes von Haugwitz * Improve handling of ACL errors 2023-07-21 Hannes von Haugwitz * Fix double free() during report generation (closes: #157) 2023-07-10 Hannes von Haugwitz * Use void for empty function parameter list 2023-07-01 Hannes von Haugwitz * Update GPG key in SECURITY.md 2023-06-29 Hannes von Haugwitz * Fix typo in aide.1 manual page 2023-06-27 Hannes von Haugwitz * Fix child directory processing on equal match (closes: #154) 2023-06-12 Hannes von Haugwitz * Add missing ')' to log message * Fix handling of extended attributes on symlinks (closes: #156) 2023-06-03 Hannes von Haugwitz * Add progress bar (closes: #120) - add new '--no-progress' parameter - log some performance data in 'info' log level * Remove strerror() calls from thread log messages * Use AIDEVERSION only once in sources * Update aide.conf.5 manual page * Adjust memory allocation error messages * Add missing files to 'autoreconf-clean' Makefile target * Don't require database_out for --dry-init * Fix static linking of the aide binary 2023-05-28 Hannes von Haugwitz * Use binary search tree to store node's children 2023-05-10 Hannes von Haugwitz * Handle readlink() errors 2023-04-03 Hannes von Haugwitz * Add another missing lock for tree operations 2023-04-01 Hannes von Haugwitz * Add missing lock for tree operations during file system scan * Use gzread instead of gzgetc 2023-03-12 Hannes von Haugwitz * Adjust documentation of num_workers config option * Require pthread (remove --without-pthread configure option) 2023-03-10 Hannes von Haugwitz * Adjust log messages about check inode attribute comparison 2023-03-08 Hannes von Haugwitz * Add warning if rules contain not compiled-in attributes (closes: #153) 2023-03-06 Hannes von Haugwitz * Remove (obsolete) Todo file 2023-03-05 Hannes von Haugwitz * Remove contrib/ scripts 2023-02-19 Hannes von Haugwitz * README: update expiration date of signing key 2023-02-18 Hannes von Haugwitz * Fix segfault when using --dry-init 2023-02-14 Hannes von Haugwitz * Fix handling of empty growing files 2023-02-06 Hannes von Haugwitz * Release aide 0.18 2023-02-05 Marc Haber * Update aide.conf.5 manual page 2023-01-22 Hannes von Haugwitz * Update man pages * Minor code cleanup * Improve some logging 2023-01-21 Hannes von Haugwitz * Adjust some log messages * Add SECURITY.md to EXTRA_DIST * Remove mmap support for hashsum calculation * Add warning if rule tree is empty * Update --help message * Update --version message 2023-01-20 Hannes von Haugwitz * Limit hashsum calculation of growing files to stat size * Refactor size mismatch warning during hash calculation * Ensure size is always written to database if growing attribute is set 2023-01-19 Hannes von Haugwitz * Fix hash calculation for growing files 2023-01-18 Hannes von Haugwitz * Also ignore bcount attribute for compressed files 2023-01-17 Hannes von Haugwitz * Fix special attributes handling when pthread is not compiled in 2023-01-16 Hannes von Haugwitz * Add 'growing' and 'compressed' special attributes - support uncompressed hashsum comparison for gzip files (closes: #33) - support hashsums for growing files (closes: #34) - 'S' attribute is now deprecated, use 'growing+s' attributes instead - replace 'S' attribute in '>' compound group with 'growing+s' - add new log level 'compare' - improve some logging 2023-01-15 Hannes von Haugwitz * Do not show 'different attributes' message for ignored attributes 2022-11-20 Sam James * Fix bashisms in build system * Fix configure.ac compatibility with Clang 16 2022-11-06 Hannes von Haugwitz * Remove Prelink support (--with-prelink configure option) 2022-11-01 Hannes von Haugwitz * Change default number of workers to 1 (single-thread) * Fix typo in aide.conf manual page 2022-09-04 Marc Haber * Allow executable config files to belong to root as well (closes: #137) 2022-08-20 Hannes von Haugwitz * Fix some compiler warnings * Handle read/write errors in parent/child communication * Escape backslash in JSON strings (closes: #136) * Improve configurability of workers - add num_workers config option (closes: #134) - accept percentage of available processors (closes: #135) 2022-08-13 Hannes von Haugwitz * Support multithreading for hashsum calculation (closes: #12) - add --without-pthread configure option - add new log level 'thread' - add new '--workers' parameter - add new exit code 23 for thread errors - require Autoconf Macro Archive (autoconf-archive) * Support restricted rules with empty restriction (closes: #133) 2022-08-09 Hannes von Haugwitz * Add exit code 22 for memory allocation errors 2022-08-01 Hannes von Haugwitz * Improve some logging 2022-07-31 Hannes von Haugwitz * Fix configure check for headers 2022-07-30 Hannes von Haugwitz * Check for gcrypt if mhash is not available 2022-07-24 Hannes von Haugwitz * Refactor configure.ac - improve --version output - use pkg-config to get link flags * Fix typo in log message (closes: #129) * Update aide.conf.5 manual page - fix backslash escaping (closes: #130) - do not start line with ' (closes: #131) * Fix deep selective matches (closes: #132) 2022-07-10 Hannes von Haugwitz * Change log level for some deprecations * Update manual pages 2022-07-09 Hannes von Haugwitz * Refactor code to scan file system * Use signal-safe write function in signal handler (closes: #100) * Fix error messsage on invalid rule prefix 2022-07-02 Hannes von Haugwitz * Fix SIGBUS handling * Fix segfault in close_md function 2022-06-28 Hannes von Haugwitz * Fork child for hash calculation (closes: #124) 2022-06-17 Hannes von Haugwitz * Adjust some log messages * Update aide.conf.5 manual page * Fix compiler warnings and clean up code * Improve error message for unknown config options 2022-06-16 Hannes von Haugwitz * Add prefix option to directory include macros (closes: #112) 2022-06-15 Hannes von Haugwitz * Add `report_format` option (closes: #18) - available formats: `plain`, `json` 2022-04-18 Hannes von Haugwitz * Fix memory leak on errors during hash calculation (closes: #125) 2022-02-20 Hannes von Haugwitz * Fix handling of duplicate database entries (closes: #122) 2022-02-13 Hannes von Haugwitz * Fix compiler warnings and clean up code 2022-02-12 Hannes von Haugwitz * Clean up #include statements 2022-01-19 Hannes von Haugwitz * Precalculate buffer size in base64 functions (CVE-2021-45417), thanks to David Bouman for reporting this issue 2022-01-18 Hannes von Haugwitz * Handle malformed database lines (closes: #122) * Always add size attribute to database if growing size group is set (closes: #121) 2021-12-31 Hannes von Haugwitz * Improve error message during config parsing (closes: #119) 2021-12-05 Hannes von Haugwitz * Add 'database_in' examples to manual page (closes: #31) * Enable dynamic linking by default (closes: #94, #96, #109) 2021-12-03 Hannes von Haugwitz * Fix autoconf warnings 2021-12-02 Hannes von Haugwitz * Remove re-introduced bashism in configure.ac 2021-12-01 Hannes von Haugwitz * Switch from PCRE to PCRE2 (closes: #116) 2021-11-14 Jason Pyeron * Add missing config.h include (closes: #104) 2021-11-07 Hannes von Haugwitz * Remove bashism in configure.ac 2021-11-05 Hannes von Haugwitz * Disable MD5 hashsum if in libgcrypt FIPS mode (closes: #110) 2021-11-04 Hannes von Haugwitz * Don't fail on missing new line at end of config file (closes: #108) 2021-10-03 Hannes von Haugwitz * Support CRLF line-endings in config files (closes: #107) 2021-06-06 Hannes von Haugwitz * Fix handling of --without-posix-acl configure option, thanks to Ilya Tumaykin for the patch * Mention removal of -r, --report command line option in man page 2021-06-05 Hannes von Haugwitz * Only use the return value of time function 2021-05-24 Hannes von Haugwitz * Fix type of database file pointer (closes: #98) 2021-05-01 Hannes von Haugwitz * Document how to ignore read-only ext2 file attributes (closes: #47) * Add @@if macro - deprecate '@@ifdef', use '@@if defined' instead - deprecate '@@ifndef', use '@@if not defined' instead - deprecate '@@ifhost', use '@@if hostame' instead - deprecate '@@ifnhost', use '@@if not hostname' instead * Add 'exists' boolean function (closes: #87) 2021-04-25 Hannes von Haugwitz * Refactor e2fsattrs code * Improve warning message for cutoff database line (closes: #91) 2021-04-21 Hannes von Haugwitz * Add 'config_check_warn_unrestricted_rules' option (closes: #44) 2021-04-18 Hannes von Haugwitz * Improve error message for negative rule with an attribute expression (closes: #90) * Document changed_attributes report level format (closes: #95) 2021-02-10 Hannes von Haugwitz * Release aide 0.17.3 2021-02-07 Hannes von Haugwitz * Fix group usage in '--after' config line 2021-02-06 Hannes von Haugwitz * Release aide 0.17.2 2021-02-02 Hannes von Haugwitz * Fix null pointer dereference in db_close() * Fix out-of-bounds read of attributes array 2021-01-30 Hannes von Haugwitz * Require file type for --path-check (closes #88) * Release aide 0.17.1 2021-01-29 Hannes von Haugwitz * Fix some typos in log messages 2021-01-27 Hannes von Haugwitz * Fix issue where 'different attributes' message is not shown 2021-01-24 Hannes von Haugwitz * Fix typos in aide.conf manual page 2021-01-24 rui * Remove leftover include of 'error.h' 2021-01-23 Hannes von Haugwitz * Release aide 0.17 2021-01-22 Hannes von Haugwitz * Update manual pages * Remove outdated aide.conf.in 2021-01-21 Hannes von Haugwitz * Update README * Print --help to stdout * Remove manual.html * Add missing free() * Limit number of nested includes 2021-01-18 Hannes von Haugwitz * Add @@x_include_setenv macro * Fix segfault when using variable without value 2021-01-17 Hannes von Haugwitz * Update copyright notices - reformat copyright statements - fix outdated FSF address 2021-01-16 Hannes von Haugwitz * Don't use autoconf input files for man pages * Add exit code 21 for file lock errors * Check for secure permissions of executable config files * Fix rule order in database lexer * Add missing source files to check_aide_SOURCES * Check return value after dynamic memory allocations * Allow empty line with white spaces * Fix off-by-one error and several memory leaks 2021-01-10 Hannes von Haugwitz * Add --dry-init command (closes #28) * Handle stderr during file execution * Fix stdout processing during script execution 2021-01-09 Hannes von Haugwitz * Add @@x_include macro (closes #6) * Adjust directory support for @@include - use regular expression filter - follow symbolic links - don't follow sub-directories 2021-01-07 Hannes von Haugwitz * Fix compiler warnings in report code * Fix default db values * Add --disable-default-db configure option * Add support to disable default config file 2021-01-06 Hannes von Haugwitz * Add directory support for @@include (closes #4) * Fail on 'verbose' option only on evaluation (closes #84) * Add 'report_append' option (closes: #5) * Remove '$Header$' tag from copyright notice 2021-01-05 Hannes von Haugwitz * Add --path-check command * Refactor restriction code * Log command in 'info' log level * Initialise report URLs after configuration parsing 2021-01-04 Hannes von Haugwitz * Check for negative matches in parent directories 2021-01-03 Hannes von Haugwitz * Reduce logging in 'rule' log level * Fix equal rule matching 2021-01-02 Hannes von Haugwitz * Adjust log message about variable redefinition * Adjust log level for 'rules referring to non-existent directory' message * Remove notice about c and I flags enabled at the same time * Extend '--version' output - output is written to stdout (instead of stderr) - add default config values - add available hashsums - add default compound groups * Fix default 'database_in' value * Add new default compound group 'H' 2021-01-01 Hannes von Haugwitz * Fix several segmentation faults * Fail on double slash in rule path 2020-12-30 Hannes von Haugwitz * Refactor logging and config parsing code - Logging related changes: - add log_level option (closes: #21) - add -L, --log-level command line option - remove 'verbose' config option - remove -V, --verbose command line option - introduce named log levels - add 'config' log level (closes: #37) - SIGUSR1 now toggles debug log level - add config file names to log output - cache log lines until log level is set - log messages and errors are always written to stderr - remove warning when input database is '/dev/null' (closes: #35) - Config parsing related changes: - add 'database_in' option (deprecates 'database' option) - handle UTF-8 in path names and rules (closes: #11) - '@' and ' ' in config/rules are now escaped with '\' (closes: #50) - fix line numbers in log messages (closes: #43) - config lines must end with a newline - (restricted) regular rules must start with '/' - allow empty value for macros (closes: #45) - early fail on regular expression errors - fail on invalid/unsupported URLs - deprecate non-alphanumeric characters in group names - code cleanup 2020-12-20 Hannes von Haugwitz * Remove config and database signing code - remove '--with-confighmactype' configure option - remove '--with-confighmackey' configure option - remove '--with-dbhmactype' configure option - remove '--with-dbhmackey' configure option 2020-12-18 Hannes von Haugwitz * aide.conf.5: clarify negative matching behaviour (closes: #82) * aide.conf.5: fix example to ignore /dev directory structure 2020-12-13 Hannes von Haugwitz * Add 'stribog256' and 'stribog512' gcrypt algorithms (closes: #69) * Adjust indent of changed attributes * Remove unused `attr` field from seltree struct * Remove obsolete aide-attributes.sh script * Refactor attributes and hashsum code - change associated letter for message digests changes to 'H' 2020-12-12 Hannes von Haugwitz * Fix report when using report_ignore_e2fsattrs * Document removal of 'ignore_list' and 'report_attributes' options * Remove unused code 2020-08-09 Hannes von Haugwitz * Fix compilation with curl - use pkg-config to get link flags * Remove db name alias code * Remove (unmaintained) Solaris ACL code - remove '--with-sun-acl' configure option * Remove PostgreSQL database backend support 2020-07-14 Hannes von Haugwitz * Fix report of added files (closes #79) 2020-07-13 Hannes von Haugwitz * Fix report when using --update (closes #78) * Fix condition for 'couldn't open file' message (closes #77) 2020-07-11 Hannes von Haugwitz * Enable gost and whirlpool checksums with gcrypt * Fix compilation with gcrypt 2020-07-09 Hannes von Haugwitz * Add support for per-report_url options (closes #19) - add 'report_level' option (see #21) - add 'report_summarize_changes' option (deprecates 'summarize_changes' option) - add 'report_grouped' option (deprecates 'grouped' option) - remove '--with-initial-errors' configure option - remove -r, --report command line option - write non-report messages to stderr - handle report_ignore_added_attrs, report_ignore_removed_attrs, report_ignore_changed_attrs, report_force_attrs as config options - code cleanup 2020-06-16 Hannes von Haugwitz * Refactor seltree code - add seltree_struct.h - add seltree.c - add rx_rule.h and rx_rule.c - fail on errors in regular expressions - code cleanup 2020-06-14 Hannes von Haugwitz * Fix compiler warnings in postgresql code * Fix compilation with postgresql support - use pkg-config to get link flags * Update copyright notices 2020-05-04 Hannes von Haugwitz * Rephrase init database warning 2020-02-25 Hannes von Haugwitz * Remove useless pointer dereference 2020-01-11 Ferenc Erki * Fix typos 2019-12-19 Peter Whittaker * Fix typo in aide.conf.5.in 2019-12-01 Hannes von Haugwitz * Add 'tests/check_aide.h' to check_aide_SOURCES * Add unit test for attributes.c * Remove unused code * Rename compare_db.[hc] to report.[hc] 2019-09-29 Hannes von Haugwitz * Rename report.h to error.h * Remove unused local m4 macros * Remove C99 compliant snprintf implementation 2019-09-22 Hannes von Haugwitz * Show changed attributes in 'different attributes' message 2019-09-22 Hannes von Haugwitz * Refactor attributes code * Remove unsued functions * Use AC_SYS_LARGEFILE for large-file support (closes #16) - require C99 compatible compiler - stop using readdir_r in favor of readdir - remove unused 'size_o member in db_line struct - '--disable-largefile' now disables LFS 2019-09-21 Hannes von Haugwitz * Fix some compiler warnings 2019-07-17 Hannes von Haugwitz * aide.conf.5: fix position of 'C' letter 2019-07-17 Julien DUBOIS * Add support for Linux capabilities 2019-07-06 Hannes von Haugwitz * Change associated letter for message digests changes * Remove unsued lex/yacc code 2019-05-19 Hannes von Haugwitz * Release version 0.16.2 2019-05-18 Hannes von Haugwitz * Fix handling of directory-restricted negative rules (closes #24) * Don't lock '/dev/null' when used as output database (closes #26) * Fix parsing of rules containing '?' quantifier 2019-04-29 Julien DUBOIS * Fix extended attributes support (xattrs) * README: fix typo 2019-03-20 Hannes von Haugwitz * Add 'autoreconf-clean' Makefile target 2019-03-16 Lukáš Jirkovský * Fix processing of go files 2019-02-25 Hannes von Haugwitz * Release version 0.16.1 2019-02-20 Hannes von Haugwitz * Explain arithmetic exit codes in aide.1, thanks to Marc Haber for the patch * Fix build against attr >= 2.4.48 (patch by Ilya Tumaykin) * Use AC_PATH_TOOL to find pkg-config 2019-02-10 Hannes von Haugwitz * Move to GitHub * Update documentation - move end user mailing list to ipi.fi - fix tabs/whitespaces - add mssing release date for 0.16 in NEWS file * Update README - mention AIDE website aide.github.io - remove broken links 2018-12-07 Hannes von Haugwitz * src/do_md.c: fix memory leak in is_prelinked (closes #103), thanks to Robert Springer for the patch 2018-06-23 Hannes von Haugwitz * Fix spelling error 2018-06-17 Hannes von Haugwitz * Fix some compiler warnings 2018-06-10 Hannes von Haugwitz * Add missing include in src/db.c (patch by Ilya Tumaykin) * src/base64.c: fix memory leak in decode_base64 (closes #95) 2018-05-31 Hannes von Haugwitz * Remove aide.spec.in * Remove contrib/mkdailyrelease.sh 2017-11-18 Hannes von Haugwitz * Fix root_prefix option 2017-10-29 Hannes von Haugwitz * Fix short form of --limit parameter 2016-07-25 Hannes von Haugwitz * Release version 0.16 2016-07-11 Hannes von Haugwitz * Fix example aide.conf (xattr -> xattrs) * aide.conf.5: update "SELECTION LINES" section * Released version 0.16rc1 2016-07-10 Hannes von Haugwitz * Fix compilation with latest libaudit * Use AC_PROG_CC_C99 instead of AC_PROG_CC * Add AM_PROG_CC_C_O * aide.conf.in: logfile -> file * Update README * Update manual pages (aide.1 and aide.conf.5) 2016-07-07 Hannes von Haugwitz * Adapt manual to version 0.16 2016-06-08 Hannes von Haugwitz * Add missing break statements 2016-04-15 Hannes von Haugwitz * Released version 0.16b1 2016-04-13 Hannes von Haugwitz * Fix spelling errors * Makefile.am: fix distribution of doc files 2016-04-11 Hannes von Haugwitz * Add 'report_ignore_changed_attrs' option, deprecate 'ignore_list' option * Add 'report_force_attrs' option, deprecate 'report_attributes' option 2016-04-08 Hannes von Haugwitz * Fix some compiler warnings 2016-04-06 Hannes von Haugwitz * Support restricted selection lines 2016-04-02 Hannes von Haugwitz * Adjust file type letters 2016-03-31 Hannes von Haugwitz * Change verbosity levels to ease debugging 2016-03-28 Hannes von Haugwitz * Fix '.*'-rule matching and code cleanup 2016-03-22 Hannes von Haugwitz * Fix compilation issue with e2fsprogs 1.43 2016-03-06 Hannes von Haugwitz * Fix report layout 2016-03-05 Hannes von Haugwitz * Fix segfault when DB_CHECKINODE is used 2016-03-02 Hannes von Haugwitz * Add new '--limit' parameter 2016-03-01 Hannes von Haugwitz * Sort entries of database file 2016-02-27 Hannes von Haugwitz * Switch to Perl 5 Compatible Regular Expressions, changes include: - require PCRE library - drop bundled GNU regexp library * src/commandconf.c: add warning if a group is redefined 2016-02-21 Hannes von Haugwitz * Add new 'database_add_metadata' option 2016-02-20 Hannes von Haugwitz * Add new 'report_quiet' option 2015-11-22 Hannes von Haugwitz * Use single Makefile.am * doc/aide.conf.5.in: minor fixes 2015-11-20 Hannes von Haugwitz * src/gen_list.c: minor code cleanup 2015-11-16 Hannes von Haugwitz * Rewrote handling of ignored/forced attributes, changes include: - new 'report_ignore_added_attrs' option - new 'report_ignore_removed_attrs' option - print human-readable info about ignored attributes in report - code cleanup - bug fixes 2015-11-07 Hannes von Haugwitz * Added new 'report_ignore_e2fsattrs' option 2015-10-31 Hannes von Haugwitz * src/gen_list.c: fixed bug if rules are removed 2015-10-28 Hannes von Haugwitz * src/compare_db.c: fixed total number of entries 2015-08-08 Hannes von Haugwitz * src/compare_db.c: added support for new e2fsattrs flags 2015-05-06 Hannes von Haugwitz * src/compare_db.c: adjusted report layout 2015-03-02 Hannes von Haugwitz * Renamed 'configure.in' to 'configure.ac' 2013-05-20 Hannes von Haugwitz * Print checksums of databases in verbose level 2 or higher (closes feature request 1502032) * Added new 'database_attrs' option * configure.in: fixed compilation with selinux * src/conf_lex.l, src/db_lex.l: fixed definition of YYDEBUG 2013-05-18 Hannes von Haugwitz * configure.in: removed check for 'libcrypt' * Renamed 'detailed_init_report' option to 'report_detailed_init' 2013-05-17 Hannes von Haugwitz * configure.in: - fixed "suspicious cache-id" warnings - removed 'AC_CONFIG_MACRO_DIR' macro * src/Makefile.am: - replaced INCLUDES with AM_CPPFLAGS 2013-05-16 Hannes von Haugwitz * Handle tilde (~) in database paths and report urls * src/compare_db.c: adjusted report layout 2013-05-14 Hannes von Haugwitz * src/db.c: fixed segfault when dbconf->db_out is NULL * Replaced fopen.c with the version from curl-7.30.0 2013-05-08 Hannes von Haugwitz * src/compare_db.c: - fixed output of checksums - use size_t as the type of for loop variable 2013-05-06 Hannes von Haugwitz * src/compare_db.c: - fixed return value of database initialization - minor code cleanup * src/db_file.c, src/do_md.c: - fixed use of unportable %m format * doc/aide.1.in: - fixed format in NOTES section - documented return value of '--compare' and '--update' command 2013-05-04 Hannes von Haugwitz * src/compare_db.c: - changed minimum verbose level for printing the details about added and removed entries to 7 * README: - updated "Source Code Verification" section * Released version 0.16a2 2012-10-10 Hannes von Haugwitz * Added new default group X * src/gen_list.c: fixed stripping of removed attributes 2012-10-08 Hannes von Haugwitz * src/gen_list.c: fixed handling of renamed files - read in databases in one go - read in old database at the end 2012-10-06 Hannes von Haugwitz * Added new report_base16 option 2012-09-05 Hannes von Haugwitz * src/compare_db.c: support older versions of e2fsprogs 2012-06-19 Hannes von Haugwitz * src/db_file.c: added missing format string to dofprintf calls 2011-10-02 Hannes von Haugwitz * Added new detailed_init_report option 2011-09-29 Hannes von Haugwitz * configure.in, include/aide.h, src/db_file.c: - fixed 'undef' compiler warnings 2011-09-24 Hannes von Haugwitz * src/gen_list.c, include/do_md.h, src/do_md.c: - moved selinux2line function to src/do_md.c - moved xattrs2line function to src/do_md.c * src/db_file.c: - declare db_writeacl only if WITH_ACL is defined 2011-09-23 Hannes von Haugwitz * include/db_disk.h, src/db_disk.c, src/db.c: - fixed 'unused-parameter' compiler warning * include/db_disk.h, src/db_disk.c: - removed unused functions (db_disk_read_spec, db_writespec_disk, db_writeline_disk, db_close_disk) * src/db_file.c: - fixed 'unused-but-set-variable' compiler warnings * src/gen_list.c, include/do_md.h, src/do_md.c: - call acl2line only if WITH_ACL is defined 2011-09-22 Hannes von Haugwitz * src/be.c: - declared static functions static * src/commandconf.c: - fixed 'unused-but-set-variable' compiler warning * src/compare_db.c: - fixed some 'format' compiler warnings * src/db.c: - fixed 'unused-but-set-variable' compiler warnings 2011-09-21 Hannes von Haugwitz * include/aide.h, src/aide.c: - declared static functions static 2011-09-20 Hannes von Haugwitz * include/aide.h, src/db_file.c: - fixed format of 8 bytes off_t type 2011-09-17 Hannes von Haugwitz * src/aide.c: - added missing #include 2011-09-09 Rami Lehti * src/base64.c, src/gen_list.c: - changed verbosity levels to ease debugging 2011-09-07 Hannes von Haugwitz * src/commandconf.c: - added missing spaces to "Cannot access config file" message 2011-09-05 Hannes von Haugwitz * Added new root_prefix option * src/do_md.c: - removed unused function (md_init_fail) 2011-09-04 Hannes von Haugwitz * include/gen_list.h, src/gen_list.c: - removed unused functions (add_file_to_list, traverse_tree, gen_list) 2011-09-03 Hannes von Haugwitz * src/gen_list.c: - print list of added files (verbose level >= 2) and their details (verbose level >= 6) if database has been initialized 2011-07-12 Hannes von Haugwitz * src/gen_list.c: - fixed has_str_changed function * src/util.c: - fixed bad free of hostname variable * src/db_file.c: - removed dead code 2011-04-08 Hannes von Haugwitz * src/gen_list.c: - fixed wrong total number of entries if comparing two databases 2011-03-29 Hannes von Haugwitz * src/compare_db.c: - rewrote gen_report function, changes included: - merged gen_report() and report_tree() - added info about verbose level, ignorelist and report_attributes to report if they differ from standard value - changed report if aide found no changes - added info about number of entries if aide found no changes or the database has been initialized - fixed report of added or removed entries if verbose level is 6 or higher and there are only added or removed entries 2011-03-24 Hannes von Haugwitz * src/compare_db.c: - made ignored_attrs and forced_attrs global - added run time to report 2011-03-22 Hannes von Haugwitz * src/compare_db.c: - print "End timestamp" message in report 2011-03-18 Hannes von Haugwitz * src/db_disk.c: - fixed handling of "/" directory inode - got rid of some static variables 2011-03-01 Hannes von Haugwitz * Removed contrib/mkgitsnapshot.sh 2011-02-16 Hannes von Haugwitz * Released version 0.16a1 2011-02-09 Hannes von Haugwitz * README: - adjusted "Source Code Verification" section 2010-12-30 Hannes von Haugwitz * src/compare_db.c: - print "Looks okay" message also in DO_DIFF mode 2010-12-29 Hannes von Haugwitz * include/compare_db.h, src/compare_db.c: - added gen_report function (code copied from src/aide.c) * src/aide.c: - removed code copied to src/compare_db.c * include/compare_db.h: - removed report_tree function 2010-12-28 Hannes von Haugwitz * src/compare_db.c: - use strftime to format timestamps - made width_details, time_format[] and time_string_len constant - added numeric timezone to the date format 2010-12-27 Hannes von Haugwitz * src/compare_db.c: - added xattrs2array, acl2array and get_attribute_values functions - added print_dbline_attributes function, changes included: - wrap attribute values instead of cut them off - side-by-side output of acl and xattrs values - use '|' to separate the old value from the new one - use node->changed_attributes instead of recalculate the changed attributes - print added or removed attributes of changed entries if forced via report_attributes - removed obsolete code - print details about added and removed entries in verbose level 6 or higher, closes feature request 1460461 - print added and removed attribute values of changed entries in verbose level 6 or higher 2010-12-26 Hannes von Haugwitz * src/compare_db.c: - fixed type of summary_char[] - fixed typo in comment 2010-11-27 Hannes von Haugwitz * doc/aide.1.in: - fixed format in FILES section - added hint on how to decode base64 encoded checksums 2010-11-26 Hannes von Haugwitz * doc/manual.html: - applied changes by Jack Blankenship 2010-11-16 Hannes von Haugwitz * src/compare_db.c: - added missing declaration of aclt variable 2010-11-14 Hannes von Haugwitz * src/conf_yacc.y: - fixed declaration of conftext variable * configure.in: - fixed compilation under Solaris * README: - added hint to use --disable-static under Solaris 10/OpenSolaris 2010-10-12 Hannes von Haugwitz * src/gen_list.c, src/do_md.c: - replaced "File" by "Entry" 2010-10-11 Hannes von Haugwitz * src/aide.c, doc/aide.conf.5.in: - enabled summarize_changes by default 2010-09-29 Hannes von Haugwitz * src/compare_db.c: - rewrote summarize_changes feature to work with node->changed_attrs - replaced "files" by "entries" - made e2fsattrs2string static - use S_IFMT to extract the file type code 2010-09-27 Hannes von Haugwitz * src/gen_list.c: - added bytecmp, has_str_changed, has_md_changed, compare_single_acl, has_acl_changed, cmp_xattr_node, have_xattrs_changed (copied and renamed from src/compare_db.c) - added get_changed_attributes function - use get_changed_attributes instead of compare_dbline - save changed attributes in node->changed_attrs * include/compare_db.h, src/compare_db.c: - removed obsolete compare_dbline function 2010-09-24 Hannes von Haugwitz * include/compare_db.h: removed init_rxlst function * include/db_config.h: include seltree.h after #define DB_ATTR_TYPE * include/seltree.h: - use DB_ATTR_TYPE instead of int for attr - added DB_ATTR_TYPE changed_attrs to seltree struct 2010-09-23 Hannes von Haugwitz * src/compare_db.c: - removed unused functions (find_line_match, init_rxlst, eat_files_indir) - compare ignorelist/forced_attrs with DB_ATTR_UNDEF instead of -1 - renamed e2fsattrs2char function to e2fsattrs2string - use str_has_changed instead of compare_str - added debug output to md_has_changed - use md_has_changed instead of compare_md_entries - removed obsolete functions (compare_str, compare_md_entries) 2010-09-17 Hannes von Haugwitz * src/compare_db.c: fixed compiler warning if WITH_AUDIT is not defined 2010-09-11 Hannes von Haugwitz * Documented '-E' in man page and '--help' text 2010-09-10 Richard van den Berg * Released version 0.15.1 * Changed version to post-0.15.1 2010-09-07 Hannes von Haugwitz * Ignore changed file name if attributes does not match * Allow absence of DB_CHECKINODE if file name has changed 2010-08-08 Richard van den Berg * Added mkgitsnapshot.sh to contrib/ * Released version 0.15 * Changed version to post-0.15 2010-08-06 Hannes von Haugwitz * Updated copyright notices of list.h, list.c, md.h, md,c, symboltable.h, symboltable.c, util.h and util.c * Escaped '-' that really mean '-' in man pages * Updated copyright notices of db_config.h, report.h, url.h, conf_yacc.y, db_lex.l and error.c 2010-08-05 Hannes von Haugwitz * Updated copyright notices of db_file.h, db_file.c, db_sql.h, db_sql.c, do_md.h, do_md.c, gen_list.h and gen_list.c 2010-08-04 Hannes von Haugwitz * Updated copyright notices of commandconf.h, commandconf.c, conf_lex.h, conf_lex.l, db.h, db.c and db_list.h 2010-08-03 Hannes von Haugwitz * Updated copyright notices of aide.h, aide.c, be.c, compare_db.h, compare_db.c and db_disk.c 2010-08-02 Richard van den Berg * Removed ], from version string when --with-curl was used, closes bug 3038382 2010-08-01 Richard van den Berg * Released version 0.15-rc1 * Changed version to post-0.15-rc1 2010-07-30 Hannes von Haugwitz * Removed obsolete compare_db function * Updated documentation of the default groups 2010-07-29 Hannes von Haugwitz * Added ftype and e2fsattrs to the default groups L, R and > 2010-07-25 Hannes von Haugwitz * Fixed sorting of files in report by filename 2010-07-24 Hannes von Haugwitz * Added new grouped option * Sort files in report by filename, see feature request 1337718 2010-07-23 Hannes von Haugwitz * Fixed indent of XAttrs output * Fixed report_attributes for XAttrs * Fixed indent of ACL output * Fixed report_attributes for ACL * Fixed report_attributes for Lname and SELinux 2010-07-22 Hannes von Haugwitz * Fixed report_attributes for checksum values * Replaced 'E2fsAttrs' by 'E2FSAttrs' * Fixed report_attributes for string and long values * summarize_changes: made summary string length also for added/removed files dynamic 2010-07-21 Hannes von Haugwitz * Fixed typo in aide.conf man page * summarize_changes: made length of summary string dynamic * Always save the inode to database (needed for DB_CHECKINODE) * Documented ftype and e2fsattrs in aide.conf * Added TFTYPE token * Prompt for ./configure and make only if autoreconf was successful 2010-07-20 Hannes von Haugwitz * Added ext2 file attributes support 2010-06-12 Hannes von Haugwitz * Always add permissions attribute to database * Added AIDEVERSION to report 2010-06-11 Hannes von Haugwitz * Adjusted old database warning message 2010-06-10 Hannes von Haugwitz * Added file type change detection support * Use DB_ATTR_TYPE for ignorelist and forced_attrs 2010-06-09 Hannes von Haugwitz * Fixed handling of size and growing size bits 2010-06-08 Hannes von Haugwitz * Another fix for the changed permissions are always reported issue 2010-06-07 Hannes von Haugwitz * Replaced 'Permissions' by 'Perm' to fit 9 columns * Fit detailed output in 80 columns, closes feature request 1337759 2010-06-05 Richard van den Berg * Released version 0.14.2 * Changed version to post-0.14.2 2010-06-05 Hannes von Haugwitz * Added missing description for '|' in aide.conf man page * Report correct file type in "Detailed information about changes" section * Fixed strcpy issue on multi-core environments 2010-06-04 Hannes von Haugwitz * Replaced 'File' by 'Entry' in database warnings * Reformatted "Entry ... has different attributes" warnings 2010-06-03 Hannes von Haugwitz * Added missing space and new line to "Error in selective regexp" message, fixes bug 1944700 * Added missing '-' to separator line in the report 2010-05-30 Richard van den Berg * Released version 0.14.1 * Changed version to post-0.14.1 2010-05-20 Richard van den Berg * Support spaces and other characters in file paths in config by Byron Darrah * Added aide-attributes.sh script by Hannes von Haugwitz 2010-05-19 Richard van den Berg * Use exit() instead of abort() by Steve Grubb * Fixed changed permissions are always reported issue by Hannes von Haugwitz 2010-04-09 Richard van den Berg * Use DB_ATTR_TYPE for compare_dbline() by Patrick Neely 2010-03-27 Richard van den Berg * Changed version to post-0.14 * Do not use += in configure, fixes bug 2972100 * Change gzdopen() from wb+ to wb, fixes bug 2976146 * Do not strcat into uninitialized data, fixes bug 2919946 * Add missing db_sql prototypes, and Sun Studio compatibility, fixes bug 2888035 * Initialize gcrypt properly, fixes bug 2763470 2010-03-16 Richard van den Berg * Released version 0.14 2010-02-26 Richard van den Berg * Changed version to post-0.14-rc3 * Fixed some AC_ARG_WITH magic * Define ENOATTR if needed by Hannes von Haugwitz 2010-02-25 Richard van den Berg * Released version 0.14-rc2 * Fix xattrs and selinux bits by Hannes von Haugwitz * Released version 0.14-rc3 2010-02-25 Steve Grubb * Additional checks for snprintf.c * Fix off64_t and other size warnings * Correct linker settings 2010-02-24 Richard van den Berg * Re-enable large file support on 32 bit systems by Steve Grubb 2010-02-23 Richard van den Berg * Show -D in --help by Steve Grubb * Refix line->attr&DB_LINKNAME is always true issue by Hannes von Haugwitz 2010-02-22 Richard van den Berg * Released version 0.14-rc1 * Changed version to post-0.14-rc1 2010-02-21 Richard van den Berg * Replaced snprintf.c with the version from rsync-2.6.9 2010-02-21 Hannes von Haugwitz * Fix checksums letter * Always save the permission to database * summarize_changes: Re-enabled file-type detection for removed files * Fix line->attr&DB_LINKNAME is always true issue * Remove localignorelist for changed nodes * Disable DB_ACL bit if acls are not supported 2010-02-18 Richard van den Berg * Adjust building of fopen.c by Steve Grubb * Fix error handling for prelink by Steve Grubb 2010-02-17 Richard van den Berg * Fix several warnings by Steve Grubb * Check LD in configure by Steve Grubb * Fix xattrs typos by Hannes von Haugwitz * Reworked summarize_changes option by Hannes von Haugwitz 2010-02-13 Richard van den Berg * Added autoconf patch from Steve Grubb * Removed AM_PROG_LIBTOOL from configure.in 2010-02-06 Hannes von Haugwitz * Fixed wrong char array size 2010-02-01 Hannes von Haugwitz * Added new option to summarize changes in output file 2009-05-15 Richard van den Berg * Prelink patch by Peter Vrabec 2007-12-20 Richard van den Berg * Fix equals matches, patch by Brian De Wolf 2007-08-22 Richard van den Berg * Turn CR/LF into LF, patch by Steve Conklin 2007-06-05 Richard van den Berg * Display complete selinux context, patch by Steve Conklin 2007-05-15 Richard van den Berg * Quit autogen.sh if required tools are not found 2007-04-27 Richard van den Berg * Only use optional groups in "make check" when enabled * Prevent segfaults in db_write_byte_base64, patch from James Antill * Fix aide.spec, patch by George Hansper 2006-12-19 Richard van den Berg * Do not warn about files not being directories 2006-12-15 Richard van den Berg * Released version 0.13.1 * Changed version to post-0.13.1 2006-12-14 Richard van den Berg * Use lseek() instead of fseek() on aide.db 2006-12-13 Richard van den Berg * Work around for error while reading gzipped aide.db files 2006-12-08 Richard van den Berg * Removed ustat dead code 2006-12-07 Richard van den Berg * Released version 0.13 * Changed version to post-0.13 2006-11-30 Richard van den Berg * Set meaningful exitcodes when --check is used (Pablo Virolainen) 2006-11-29 Richard van den Berg * Changed version to post-0.13-rc2 * Check for WHIRLPOOL so old mhash can be used (Pablo Virolainen) 2006-11-25 Richard van den Berg * Fix error message about HAVAL and CRC32 with --update and gcrypt * Fix --with and --without logic of configure * Make --without switches of configure work * Released version 0.13-rc2 2006-11-24 Richard van den Berg * Remove stpcpy declaration because it is not defined in util.c * Fix segfault when line->cntx is NULL * Add --without-mhash to configure * Don't use DB_SELINUX and DB_XATTR when not present * Fix use of libgcrypt * Add new group 'l' to detect changed link name * Update documentation with new groups * Supply strnlen in utils.c * Released version 0.13-rc1 2006-11-15 Richard van den Berg * Fix syslog URLs (Yves Mettier ) 2006-10-30 Richard van den Berg * Make --with-selinux work without pkg-config 2006-10-27 Richard van den Berg * Added "Add xattr support" patch from James Antill * Added "report miscompares to Linux Audit System" patch from James Antill * Added "Allow building without mhash library" patch from James Antill * Added "correct db_names" patch from Steve Grubb * Added "memory leaks and performance updates" patch from Steve Grubb * Added "deadcode removal" patch from Steve Grubb * Added "change K&R functions to void functions" patch from Steve Grubb * Added "Memleak fix for ACLs, SELinux, XAttr" patch from James Antill 2006-10-10 Richard van den Berg * Added note about rpl_malloc on AIX 5.3 with mhash * Include version.m4 in distribution tar file * No need for absolute $(srcdir) in configure * Use AC_CONFIG_FILES(files..) instead of AC_OUTPUT(files..) * Removed redundant targets from Makefile.am 2006-10-06 Richard van den Berg * Changed version to post-0.12 * Added file locking for output files 2006-10-05 Richard van den Berg * Released version 0.12 2006-10-04 Richard van den Berg * Close database files earlier * Released version 0.12-rc2 2006-09-24 Richard van den Berg * Fixed filesize stored in postgres (SF bug #1177758) 2006-07-15 Richard van den Berg * Released version 0.12-rc1 * Remove the use of NODE_ADD_CHILDREN, hopefully it is no longer needed * Added syntax changed from 10-manpages.dpatch * Added newlines as per SF bug #1461182 * Added report_attributes group (Pablo Virolainen) 2006-06-13 Richard van den Berg * Fix stat type in report_tree() (Heiko Lehmann ) 2006-05-31 Richard van den Berg * Added support for posix_fadvice() (Pablo Virolainen) 2006-04-22 Richard van den Berg * Fix seg faults on OpenBSD (Axel Rau ) 2006-04-22 Richard van den Berg * Fix mmap on HPUX (fredrik@soderblom.org patch 1474555) 2006-03-31 Richard van den Berg * Abort if aide.db does not have checksum when FORCEDBMD is used * Explain aide.conf and aide.db signing 2006-03-29 Richard van den Berg * Add spaces to error messages (Marc Haber) * Don't warn about rules referring to non-existent directories by default 2006-03-25 Richard van den Berg * Allow aide.db to be supplied on stdin (Pablo Virolainen) * Add patch to allow http/https/ftp URLs through libcurl (Pablo Virolainen) 2006-03-17 Richard van den Berg * Use system strnstr when available * Add --disable-static flag to configure 2006-03-13 Richard van den Berg * Applied manual patch from Marc Haber * Added note about problems with mhash 0.9.x 2006-03-12 Richard van den Berg * Mordernize use of AM_INIT_AUTOMAKE * Use AIDEVERSION to avoid clash with VERSION of other packages 2006-02-26 Richard van den Berg * Use @sysconfdir@ as directory in aide.1, SF bug #1438995 2006-02-23 Richard van den Berg * Set AIDEVERSION right after including config.h * Added note about SIGTERM (Marc Haber) 2006-02-18 Richard van den Berg * Released version 0.11 * Changed version to post-0.11 2006-02-14 Richard van den Berg * Fix the broken @@ifhost and @@ifnhost directives by lcn2 (SF bug #1430482) 2006-02-09 Richard van den Berg * Fall back to strtoimax if strtoll is not available * Protect against non existing syslog facilities * Updated aide.spec.in as suggested in SF bug #1428576 2006-02-08 Richard van den Berg * Explicitly check for readdir64, by Virolainen Pablo * Added note about --disable-lfs in README 2006-01-30 Richard van den Berg * Released version 0.11-rc3 * Changed version to post-0.11-rc3 2006-01-29 Richard van den Berg * Fix layout of aide.conf.5 by Vincent Danen * Cleanup --help output by Vincent Danen * Add separators in --check output by Vincent Danen * Add --disable-lfs option to configure 2006-01-22 Richard van den Berg * Allow report_url to change syslog facility * Only warn when DB_CHECKINODE and DB_CTIME are used together * Added GPG scripts by Vincent Danen 2005-12-19 Richard van den Berg * Revert check_list_for_match to old behaviour (Marc Haber) * Documentation update (Marc Haber) 2005-12-12 Richard van den Berg * Log tree matching verbosely, patch by Virolainen Pablo 2005-11-15 Richard van den Berg * Applied 'allow removed files' patch by Virolainen Pablo 2005-11-13 Richard van den Berg * Applied fix to ANF by Virolainen Pablo 2005-11-07 Richard van den Berg * Applied 'allow new files' patch by Virolainen Pablo 2005-11-03 Richard van den Berg * Remove russian translations; they are out of date and there is no static version of gettext available * Do not stop parsing directory at unescaped . * Fix "make dist" and "make check" * Added gpg scripts to contrib * Released version 0.11-rc2 * Changed version to post-0.11-rc2 2005-10-30 Richard van den Berg * Warn if 'I' and 'c' are used together 2005-10-28 Richard van den Berg * Ignore 'c' when 'I' is in effect * Mention in aide.conf.5 that 'c' and 'I' are incompatible 2005-10-26 Richard van den Berg * Check for ino64_t and dirent64 separately since HPUX does not have them 2005-10-25 Richard van den Berg * Print start and stop timestamp together (Marc Haber ) * Print database_out path with -i and -u * Added bzip2.sh to the contrib directory 2005-10-19 Richard van den Berg * Applied patch from Debian bug #121717: aide spelling fixes 2005-10-16 Richard van den Berg * Applied patch 1124758: fix underquoted m4 * Applied patch 1124757: dist-hook missing file snprintf.h * Applied patch 1124760: cleaner automake initialisation * Applied patch 1124782: gettextize related patch 2005-10-07 Richard van den Berg * If open() with NO_ATIME fails, try open() again without it 2005-10-05 Richard van den Berg * Compile aide as a static executable * Fixed some spelling errors caught by Marc Haber * Changed version to Post 0.11-rc1 * Ignore special characters after backslash in directory names (bug #1162575) 2005-10-04 Richard van den Berg * Released aide 0.11-rc1 2005-09-14 Richard van den Berg * Print detailed error message when mmap() returns MAP_FAILED 2005-09-02 Richard van den Berg * Added patch for cygwin compatibility as per bug #1279818 2005-08-10 Richard van den Berg * Open files with O_NOATIME on Linux (per Vlada Macek ) 2005-08-08 Richard van den Berg * Reset fs.st_rdev in 2 additional places as per bug #1253822 2005-06-30 Richard van den Berg * Removed return in conf_lex.l that caused --after to be ignored 2005-06-12 Richard van den Berg * Applied another aide.1.in from Sven Hoexter 2005-06-11 Richard van den Berg * Applied aide.1.in patch from SF bug #1217483 2005-04-28 Richard van den Berg * Added long long support for portable snprintf * Created aide.conf.5.in and aide.conf.5.ru.in as per bug #1103719 2005-04-27 Richard van den Berg * Fixed sshaide.sh as suggested in bug #1100740 * Removed db_writeacl() from db_disk.c as suggested in bug #1143889 * Set st_rdev to 0 when not used as suggested in bug #1169697 2005-04-18 Richard van den Berg * Correctly parse multiple backslashes in file names 2005-04-08 Richard van den Berg * Use configure to define type for storage of file size in aide.db * Applied fix suggested in Debian Bug #237969 2005-04-06 Richard van den Berg * Always include aide.h before any other include file * Include aide.h instead of config.h to avoid multiple inclusions * Fixed large file under Solaris * Make large file support generic (not just for Solaris) 2005-04-05 Richard van den Berg * Fixed bug where shrinking files with S set where not detected 2005-02-20 Richard van den Berg * Removed extra gen_tree() as suggested in patch 985632 * Allow escaping of spaces in filenames (Virolainen Pablo ) * Allow @@{HOSTNAME} usage in aide.conf (Virolainen Pablo ) 2004-11-16 Richard van den Berg * Applied patch 984424: bug fix for "--check recurses when it shouldn't" * Applied patch 853842: sshaide - contributed script 2004-11-12 Richard van den Berg * Fixed patch from Virolainen Pablo * Applied patch id 931224: Ignoring moved files 2004-11-05 Richard van den Berg * Applied patch from Virolainen Pablo to give more infomation when file attributes have changed before calculating the hash 2004-11-04 Richard van den Berg * Make sure readdir_r is POSIX compliant before we use it 2004-11-03 Richard van den Berg * Applied patch 1058973: Please don't add -I$(prefix)/include * Fixed bug 836253: Manual is wrong about --check command * Applied fix in config parser to avoid 10000 line limit 2004-11-02 Richard van den Berg * Fixed various documentation bugs filed as sf.net 2004-10-29 Richard van den Berg * Use syslog() for systems that do not have vsyslog() * Fixed file system traversing bug for systems without readdir_r * Fixed bug 836257: Line numbers in verbose output off by one 2004-10-28 Richard van den Berg * Removed config.h.in * Added ISO C99 compliant snprintf for systems that do not have it 2004-10-26 Richard van den Berg * Added check for ISO C99 compliant vsnprintf to configure.in 2004-10-23 Richard van den Berg * Applied PSQL patch from Marc Giger * Set version to "Post 0.10" * Removed aide.1 and aide.1.ru since they are created by configure * Moved #endif for WITH_MHASH in commandconf.c thanks to berkeley@octagon.com.au 2003-12-08 Richard van den Berg * Applied patch 853842 "sshaide - contributed script" * Applied patch 855639 "Updated README file" 2003-12-02 Richard van den Berg * Fixed bug 851671 Aide-0.10 --config-check dumps core 2003-11-28 Richard van den Berg * Released aide version 0.10 * Applied patch 849857 "cosmetic report fix" thanks to John Kristoff 2003-11-25 Mike Markley * Applied patch from bug 848664 "crash in db_input_wrapper (gzip)" thanks to Matt Kettler 2003-11-04 Richard van den Berg * Fixed typo in compare_db.c, closes bug 836255 thanks to Michael Schwendt * Applied patch 801860, fixes bug 801857 "=/$ gives segfault" thanks to Michael Schwendt * Applied patch 803001 "Fix for some memory leaks" thanks to Michael Schwendt * Applied patch 801853 "getopt optstring is wrong" thanks to Michael Schwendt 2003-10-03 Richard van den Berg * Moved project over to http://sf.net/projects/aide * Fixed problems in conf_yacc.y * Gzip code now uses best (-9) compression 2002-07-22 Rami Lehti * Fixed Unimplemented error message when conf md not compiled in * Fixed error message about nonexistant files. * Fixed --with-extra-includes --with-extra-libs handling (I hope) * Fixed *stat handling 2002-06-04 Rami Lehti * Released 0.9 2002-05-31 Rami Lehti * Fixed a bug in memory handling causing corrupt md's * Added --without-mmap configure option 2002-05-29 Rami Lehti * Updated version to 0.9 * Fixed loads of bugs * This file should be updated more often * Added support for md checked config and db * Updated Copyright notices * Changed checking algorithm (threading here we come) 2002-02-10 Rami Lehti * Fixed loads and loads of bugs * Added syslog backend * Report format changed * added lots of parameters see man page and configure --help * added ACL support for SunOS 5.x (and compatibles) * Released 0.8 (This is an unstable release) 2000-04-27 Rami Lehti * Added static link flag checking * Released 0.7 2000-04-13 Rami Lehti * Added linkname checking * Removed mhash snefru and fixed haval * Mhash 0.8.1 required. 2000-02-08 Rami Lehti * Changed version to 0.7 2000-02-08 Rami Lehti * Fixed core dump bug in compare_db * Added warning when config has changed * Released 0.6 2000-01-18 Virolainen Pablo * Handles config filename '-' as stdin. Manpage update. 1999-12-30 Rami Lehti * Fixed compilation problem with glibc 2.1 1999-12-29 Rami Lehti * Finally fixed wrong md5 sums. * Fixed nonprintable filename encoding. * Fixed a huge memory leak. 16k per databaseline. 1999-12-08 Pablo Virolainen * Check for [acm]times beeing in future is done correctly now. * blockcount will now be writen to database... 1999-12-02 Pablo Virolainen * Added warning if file's [acm]time is in future (gen_list.c) 1999-11-25 Rami Lehti * Added support for unknown @@ tokens in databases 1999-11-25 Pablo Virolainen * Ignorelist for reports implemented. * Block count added. It might be usefull with file with holes. 1999-11-24 Pablo Virolainen * Added '^' to first charaster of every regexpr * Minor changes do_md.c 1999-11-23 Rami Lehti * Fixed MHASH_COMPATIBILITY problem. Mhash library version 0.6.1 is now required. * Began tidying up the code so that both the internal and mhash hashes can be used at the same time. 1999-11-05 Pablo Virolainen * Fixed bug in tree traverce. Now works without permission check. 1999-10-26 Rami Lehti * Added support for mhash library (done mostly by pablo) * Fixed a --with-config-file bug in configure.in * Fixed md bug when using internal functions * Finally updated the Changelog 1999-08-26 Rami Lehti * Fixed config file handling (Wed, 25 Aug 1999 11:03:34 (EET):rammer) Changed: ChangeLog,configure.in Upped version to 0.4 (Thu, 26 Aug 1999 16:36:14 (EET):rammer) Changed: configure aide.conf.5 compare_db.c,gen_list.c,util.c util.h,conf_lex.l Fixed a bug in gen_seltree Changed default behaviour of verbositylevel 5. Now it prints the detailed info about changed files too. Now on level 5 if a dir is added a warning is shown that foo files were added under the previous dir and not the files themselves. On level 20 the behaviour is still the same. --------------------- aide-0.19.3/NEWS0000644000175000017500000003657415137354776014470 0ustar00hvhaugwitzhvhaugwitzVersion 0.19.3 (2026-01-31) * Fix st_rdev handling * Fix typos in README, NEWS and aide.conf.5 Version 0.19.2 (2025-08-13) * Security bug fixes - CVE-2025-54389: Escape control characters in report and log output - CVE-2025-54409: Fix null pointer dereference after reading incorrectly encoded xattr attributes from database Version 0.19.1 (2025-07-06) * Fix race condition when adding new nodes * Extend expiration dates of GPG key in SECURITY.md * Define MAGIC constants added since Linux 4.9 Version 0.19 (2025-04-05) * BACKWARDS INCOMPATIBLE CHANGES - switch from libmhash to libnettle - semantic change of unrestricted negative rules (!): The children and sub-directories of matching directories are no longer ignored by default but recursed into and only ignored if they also match the regular expression. This makes the behaviour consistent with restricted (recursive) negative rules. Use the new non-recursive negative rules (-) to always ignore children and sub-directories of matched directories. - 'database' config option is no longer supported, use 'database_in' instead - 'summarize_changes' config option is no longer supported, use 'report_summarize_changes' instead - 'grouped' config option is no longer supported, use 'report_grouped' instead - an incomplete written input database is now handled as an error - SIGHUP and SIGTERM are no longer ignored - SIGINT, SIGTERM or SIGHUP are now handled by removing an incompletely written database (if file was created by aide) and exiting aide (code 25) - move COMPARE log level before RULE log level - switch hashsum in default R group from md5 to sha3_256 - remove unsupported hashsums (haval, crc32, crc32b, tiger, whirlpool) - H default group now contains all compiled in hashsums that are not deprecated - rules are no longer applied to the database entries but only to the file system entries, meaning aide displays files/directories that are no longer matched by any rule as removed entries in the report - require pthread (remove --without-pthread configure option) - remove contrib/ scripts * Deprecations (to be removed in the release after next): - md5 hashsum - sha1 hashsum - rmd160 hashsum - gost hashsum * Add support for file system type restricted rules (Linux only) - add 'fstype' attribute - add '--without-fstype' configure option * Add 'version_ge' boolean operator * Add limited support for hashsum transitions (see aide.conf(5) for details) * Add 'sha512_256', sha3_256, and 'sha3_512' hashsums * Add AIDE_VERSION macro variable * Add progress bar (add '--no-progress' parameter) * Add log level 'limit' * Add colors to log output (add '--no-color' parameter) * Add '--list' command (to list database in human readable format) * Add new error codes - 24: database error - 25: received SIGINT, SIGTERM or SIGHUP signal * Performance improvements * Improve error handling * Improve logging * Update documentation * Bug fixes * Code clean up * Add more unit tests Version 0.18 (2023-02-06) * BACKWARDS INCOMPATIBLE CHANGES - remove Prelink support (--with-prelink configure option) * Switch from PCRE to PCRE2 * Enable dynamic linking by default * Support multithreading for hashsum calculation - add num_workers config option (default to single worker thread) - add new '--workers' parameter - add new log level 'thread' - add new exit code 23 for thread errors - add --without-pthread configure option - require Autoconf Macro Archive (autoconf-archive) * Remove mmap support for hashsum calculation * Deprecations (to be removed in the release after next): - 'S' attribute is now deprecated, use 'growing+s' attributes instead - '@@ifdef', macro is now deprecated, use '@@if defined' instead - '@@ifndef', macro is now deprecated, use '@@if not defined' instead - '@@ifhost', macro is now deprecated, use '@@if hostname' instead - '@@ifnhost', macro is now deprecated, use '@@if not hostname' instead * Add new 'growing' attribute * Add new 'compressed' attribute * Add new log level 'compare' * Replace 'S' attribute in '>' compound group with 'growing+s' * Add 'report_format' option (available formats: `plain`, `json`) * Add @@if macro * Add 'exists' boolean function * Add 'config_check_warn_unrestricted_rules' option * Support restricted rules with empty restriction * Add prefix option to directory include macros * Add exit code 22 for memory allocation errors * Update e2fs attributes to match upstream - the 'h' attribute has been removed - use `report_ignore_e2fsattrs=VNIE` to ignore read only attributes * Support CRLF line-endings in config files * Use pkg-config to get link flags * Add SECURITY.md * Improve logging * Improve error messages during config parsing * Update documentation * Minor bug fixes * Code clean up Version 0.17.4 (2022-01-19) * SECURITY FIX - Precalculate buffer size in base64 functions (CVE-2021-45417) Version 0.17.3 (2021-02-10) * Fix group usage in '--after' config line Version 0.17.2 (2021-02-06) * Fix null pointer dereference in db_close() * Fix out-of-bounds read of attributes array Version 0.17.1 (2021-01-30) * Require file type for --path-check * Fix issue where 'different attributes' message is not shown * Remove leftover include of 'error.h' (fixes build on macOS) * Fix typos Version 0.17 (2021-01-23) * BACKWARDS INCOMPATIBLE CHANGES - '--verbose' command line option and 'verbose' config option are no longer supported, use 'log_level' and 'report_level' options instead - '--report' command line option is no longer supported, use 'report_url' config option instead - 'ignore_list' config option is no longer supported, use 'report_ignore_changed_attrs' instead - 'report_attributes' config option is no longer supported, use 'report_force_attrs' instead - (restricted) regular rules must start with literal '/', i.e. the rule cannot begin with a macro variable - config lines must end with new line - '@' and ' ' in the configuration are now escaped with '\', that means to match a '\' you have to use four backslashes '\\\\' in your rules - 'gzip_dbout=false' fails now with config error when no zlib support is compiled in - remove '--with-initial-errors' configure option - remove PostgreSQL database backend support - remove Sun ACL support - remove config and database signing support * Enhancements: - add new '--log-level' command line option and 'log_level' config option - introduce named log levels - add new 'report' log level to help to debug rule matching - add new 'config' log level to help to debug config and rule parsing - add new '--dry-init' command - add new '--path-check' command - add directory support for @@include - add new @@x_include config macro - add new @@x_include_setenv config macro - add new default compound group 'H' (all compiled-in hashsums) - add support for per-report_url options - add new 'report_level' config option - add new 'report_append' config option - add exit code 21 for file lock errors - add default config values, available hashsums and compound groups to '--version' output - add Linux capabilities support - show changed attributes in 'different attributes' message - enable 'gost' and 'whirlpool' checksums when using gcrypt - add 'stribog256' and 'stribog512' gcrypt algorithms - add config file names to log output * Miscellaneous behaviour changes: - 'report_summarize_changes': hashsum changes are now indicated with 'H' - print '--help' and '--version' output to stdout - log messages and errors are always written to stderr - initialise report URLs after configuration parsing - allow empty values for macro variables - SIGUSR1 now toggles debug log level - fail on errors in regular expressions during config parsing - fail on invalid URLs during config check - Fail on double slash in rule path - cache log lines when 'log_level' is not yet set * Deprecations: - 'database' config option is now deprecated, use 'database_in' instead - 'summarize_changes' config option is now deprecated, use 'report_summarize_changes' instead - 'grouped' config option is now deprecated, use 'report_grouped' instead - non-alphanumeric group names are deprecated * Notable bug fixes: - fix line numbers in log messages - remove warning when input database is '/dev/null' - correctly handle UTF-8 in path names and rules - fix compilation with curl and gcrypt - warn on unsupported hash algorithms - improve large-file support * Build system changes: - require C99 compatible compiler - require pkg-config - '--disable-default-db configure option disables default database values - '--without-config' configure option now disables default config file * Remove obsolete aide-attributes.sh script * Remove outdated example aide.conf and manual.html * Fix compiler warnings * Update documentation * Minor bug fixes * Code clean up Version 0.16.2 (2019-05-19) * Bug fixes - Fix handling of directory-restricted negative rules - Don't lock '/dev/null' when used as output database - Fix parsing of rules containing '?' quantifier - Fix extended attributes support (xattrs) - Fix processing of go files * Please note: - The addition of the "trusted.*", "user.*" and the "security.*" namespaces to the xattrs attribute might lead to a vast amount of reported changed entries during your next AIDE run. You can use the `report_ignore_changed_attrs` option (see aide.conf(5)) to ignore changes of the xattrs attribute; but be aware that this will exclude the expected but also the unexpected (potentially malicious) changes. Version 0.16.1 (2019-02-25) * Move to GitHub * Update documentation * Bug fixes Version 0.16 (2016-07-25) * BACKWARDS INCOMPATIBLE CHANGES: - Negative selection lines of the form '! ' are no longer supported (use '!' instead) - The switch to Perl 5 Compatible Regular Expressions and the fix of '.*'-rule matching may result in different rule matching behaviour * Support restricted selection lines * Switch to PCRE library (drops bundled GNU regexp library) * New config options: - database_add_metadata - database_attrs - report_base16 - report_detailed_init - report_force_attrs (deprecates report_attributes) - report_ignore_added_attrs - report_ignore_removed_attrs - report_ignore_changed_attrs (deprecates ignore_list) - report_ignore_e2fsattrs - report_quiet - root_prefix * New '--limit' parameter * Report changes: - enable summarize_changes by default - use '|' to separate the old value from the new one - wrap attribute values instead of cut them off - side-by-side output of acl and xattrs values - adjust file type letters in summarize_changes output - add numeric timezone to time string - add info about verbose level to report if it differs from standard value - add info about number of entries if aide found no changes or the database has been initialized - add run time to report - print "End timestamp" message in report - print human-readable info about ignored and forced attributes in report - print checksums of databases in verbose level 2 or higher - print added and removed attribute values of changed entries in verbose level 6 or higher - print details about added and removed entries in verbose level 7 or higher - print added or removed attributes of changed entries if forced via report_force_attrs * New default group: X * Fix '.*'-rule matching * Handle tilde (~) in database paths and report urls * Sort entries of database file * Compare database entries just once * Add warning if a group is redefined * Update documentation * Bug fixes * Code clean up Version 0.15.1 * Fixed bug with DB_CHECKINODE Version 0.15 * Added new grouped option * Sort files in report by filename * Added support for e2fsattrs attribute * Added support for ftype attribute * Bug fixes Version 0.14.2 * Report correct file type in "Detailed information about changes" section * Bug fixes Version 0.14.1 * Added aide-attributes.sh contrib script * Bug fixes Version 0.14 * Renewed autoconf mechanism * Resolved licensing conflicts * New feature to summarize changes * Added prelink support * Many bugfixes Version 0.13.1 * Fixed bug with reading gzipped aide.db files * Removed dead ustat code Version 0.13 * Added support for selinux and xattr attributes (kindly contributed by Red Hat) * Added support for the Linux Audit System (kindly contributed by Red Hat) * Fixed usage of libgcrypt instead of libmhash * Added file locking for output files * Fixed bugs Version 0.12 * Fixed bugs * Allow http/https/ftp URLs through libcurl * Support posix_fadvice() to avoid caching files Version 0.11 * Fixed many bugs * Updated automake/autoconf scripts * Use snprintf by Mark Martinec if not in C library * Support for more (legacy) Unix systems and cygwin * Open files with O_NOATIME on supported Linux systems * Added I/ANF/ARF directives Version 0.10 * Fixed bugs * Moved project over to sourceforge.net * Change of project ownership Version 0.9 * Fixed bugs * Added support for keyed md check of db and config * Removed dependancy on libgcrypt * Added dependancy on mhash Version 0.8 * Fixed loads and loads of bugs * Added syslog backend * Report format changed * added lots of parameters see man page and configure --help * added ACL support for SunOS 5.x (and compatibles) * libgcrypt is now separate and required Version 0.7 * Bug fixes * Compressed database support * Linkname checking * Mhash support (version 0.8.1 of mhash required) Version 0.6 * Bug fixes * Mhash support fixed * MD sums fixed for now Version 0.5 * Bug fixes * ignore_list support * Mhash library support (version 0.6.1 of mhash required) * Disclaimer notices Version 0.4 * Bug fixes Version 0.3 * Added --update command * some bugfixes Version 0.2 * Bugfix release Version 0.1 * Implemented lots of stuff Version 0.0.0.1 * Nothing yet aide-0.19.3/acinclude.m40000644000175000017500000000743214774422002016131 0ustar00hvhaugwitzhvhaugwitzdnl AIDE_PKG_CHECK_MODULES(OPTION, PREFIX, LIBRARY, VERSION) AC_DEFUN([AIDE_PKG_CHECK_MODULES], [ if test "$aide_static_choice" = "yes"; then PKG_CHECK_MODULES_STATIC($2, [$3 $4], [], [AC_MSG_ERROR([$3 $4 not found by pkg-config - Try --without-$1 or add directory containing $3.pc to PKG_CONFIG_PATH environment variable])]) else PKG_CHECK_MODULES($2, [$3 $4], [], [AC_MSG_ERROR([$3 $4 not found by pkg-config - Try --without-$1 or add directory containing $3.pc to PKG_CONFIG_PATH environment variable])]) fi AC_DEFINE(WITH_$2,1,[Define to 1 if $3 is available]) ]) dnl AIDE_PKG_CHECK_MODULES_OPTIONAL(OPTION, PREFIX, LIBRARY, VERSION) AC_DEFUN([AIDE_PKG_CHECK_MODULES_OPTIONAL], [ AS_IF([test x"$with_$1" != xno], [ if test "$aide_static_choice" = "yes"; then PKG_CHECK_MODULES_STATIC($2, [$3 $4], [ with_$1=yes ], [ AS_IF([test x"$with_$1" = xyes], [ AC_MSG_ERROR([$3 $4 not found by pkg-config - Try to add directory containing $3.pc to PKG_CONFIG_PATH environment variable]) ]) with_$1=no ]) else PKG_CHECK_MODULES($2, [$3 $4], [ with_$1=yes ], [ AS_IF([test x"$with_$1" = xyes], [ AC_MSG_ERROR([$3 $4 not found by pkg-config - Try to add directory containing $3.pc to PKG_CONFIG_PATH environment variable]) ]) with_$1=no ]) fi AS_IF([test x"$with_$1" = xyes], [ AC_DEFINE(WITH_$2,1,[Define to 1 if $3 is available]) ]) ]) ]) dnl AIDE_PKG_CHECK(OPTION, DESCRIPTION, DEFAULT, PREFIX, LIBRARY, EXTRA_GROUP, VERSION) AC_DEFUN([AIDE_PKG_CHECK], [ AC_MSG_CHECKING(for $2) AC_ARG_WITH([$1], AS_HELP_STRING([--with-$1], [use $2 (default: $3)]), [with_$5=$withval], [with_$5=$3]) AS_IF([test x"$with_$5" = xyes], [ AC_MSG_RESULT(yes) AIDE_PKG_CHECK_MODULES($1, $4, $5, $7) if test -n $6; then aideextragroups="${aideextragroups}+$6" fi ],[ AC_MSG_RESULT(no) ]) compoptionstring="${compoptionstring}use $2: $with_$5\\n" AM_CONDITIONAL(HAVE_$4, [test "x$$4_LIBS" != "x"]) ]) dnl AIDE_PKG_CHECK_MANDATORY(DESCRIPTION, PREFIX, LIBRARY) AC_DEFUN([AIDE_PKG_CHECK_MANDATORY], [ if test "$aide_static_choice" = "yes"; then PKG_CHECK_MODULES_STATIC($2, [$3], [], [AC_MSG_ERROR([$3 not found by pkg-config - Try to add directory containing $3.pc to PKG_CONFIG_PATH environment variable])]) else PKG_CHECK_MODULES($2, [$3], [], [AC_MSG_ERROR([$3 not found by pkg-config - Try to add directory containing $3.pc to PKG_CONFIG_PATH environment variable])]) fi compoptionstring="${compoptionstring}use $1: mandatory\\n" ]) dnl AIDE_PKG_CHECK_HEADERS(OPTION, DESCRIPTION, DEFAULT, PREFIX, HEADERS) AC_DEFUN([AIDE_PKG_CHECK_HEADERS], [ AC_MSG_CHECKING(for $1) AC_ARG_WITH([$1], AS_HELP_STRING([--with-$1], [$2 (default: $3)]), [with_$1=$withval], [with_$1=$3]) AC_MSG_RESULT([$with_$1]) AS_IF([test x"$with_$1" != xno], [ AC_CHECK_HEADERS($5, [ AS_IF([test x"$3" != xno], [ AC_DEFINE(WITH_$4,1,[Define to 1 if $1 is available]) with_$1="yes" ]) ], [ AS_IF([test x"$3" = xyes], [ AC_MSG_ERROR([headers $5 for $1 not found]) ]) ]) ]) compoptionstring="${compoptionstring}use $2: $with_$1\\n" AM_CONDITIONAL(HAVE_$4, [test "x$with_$1" = "xyes"]) ]) dnl AIDE_COMPILE_TIME_OPTION(OPTION, WITH_HELP_STRING, DESCRIPTION, DEFAULT) AC_DEFUN([AIDE_COMPILE_TIME_OPTION], [ AC_MSG_CHECKING(for $3) AC_ARG_WITH([$1], AS_HELP_STRING([--with-$2], [$3 (default: $4)]), [with_$1=$withval], [with_$1=$4]) AC_MSG_RESULT([$with_$1]) compoptionstring="${compoptionstring}$3: $with_$1\\n" ]) aide-0.19.3/README0000644000175000017500000001333115137354776014633 0ustar00hvhaugwitzhvhaugwitz AIDE - Advanced Intrusion Detection Environment ------------------------------------------------- Version 0.19.3 This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Introduction ------------ AIDE is a tool for monitoring file system changes. It can be used to detect unauthorized monitored files and directories. AIDE was written to be a simple and free alternative to Tripwire. Features currently included in AIDE are as follows: o File attributes monitored: permissions, inode, user, group file size, mtime, atime, ctime, links and growing size. o Multiple checksums and hashes supported o Plain text configuration files and database for simplicity. o Rules, variables and macros that can be customized to local site or system policies. o Powerful regular expression support to selectively include or exclude files and directories to be monitored. o gzip database compression if zlib support is compiled in. o Free software licensed under the GNU General Public License v2. The homepage of AIDE is https://aide.github.io Current Version --------------- AIDE is currently maintained on GitHub. Please visit https://github.com/aide/aide/ to get the newest version of the source code. Documentation ------------- The documentation for AIDE can be found in the doc/ directory. Installation ------------ If you are using a git version of the source you need to generate the configuration files first: $ ./autogen.sh For generic installation instructions please see the INSTALL file (generated by autogen.sh). In short, just type: $ ./configure $ make $ make install See './configure --help' for the available configuration options. Dynamic versus Static Linking ----------------------------- Formerly aide was linked statically by default to reduce the attack vector of compromised shared libraries and to ease client/server monitoring configurations. However an attacker could still simply replace the statically linked binary, tamper the database file or use dynamically loaded kernel modules to change the behaviour of AIDE. These days many Linux distributions (eg CentOS/Oracle Linux), operating systems (eg Mac OS/OpenSolaris) and libraries have dropped support for static linking. Hence starting with release v0.18 AIDE is linked dynamically by default. To re-enable static linking use '--enable-static' when configuring AIDE. Source Code Verification ------------------------ We highly recommend checking that the version of AIDE downloaded and installed is an original and unmodified one. You can either verify the source tarball or the git tag. To check the supplied signature with GnuPG: $ gpg --verify aide-.tar.gz.asc This checks that the detached signature file is indeed a signature of aide-.tar.gz. To validate the gpg signature of the git tag: $ git verify-tag v The current public key needed for signature verification is: pub 4096R/68E7B931 2011-06-28 [expires: 2025-06-27] uid Hannes von Haugwitz If you do not have this key, you can get it from one of the well known PGP key servers. You have to make sure that the key you install is not a faked one. You can do this with reasonable assurance by comparing the output of: $ gpg --fingerprint 2BBBD30FAAB29B3253BCFBA6F6947DAB68E7B931 with the fingerprint published elsewhere. Requirements ------------ AIDE requires the following development tools: o C99 compatible compiler. o GNU Autoconf o GNU Autoconf Macro Archive o GNU Automake o GNU flex. o GNU yacc (bison). o GNU make. o pkg-config o PCRE2 library (libpcre2-8, library with 8-bit code unit support) o libnettle (>= 3.7) or libgcrypt o libcheck (optional, needed for 'make check', license: LGPL-2.1) Note: flex version 2.5.31 is broken, you might see the following error conf_lex.c: In function `conflex': conf_lex.c:4728: error: `yy_prev_more_offset' undeclared (first use in this function) conf_lex.c:4728: error: (Each undeclared identifier is reported only once conf_lex.c:4728: error: for each function it appears in.) Either downgrade to flex 2.5.4 or get an updated version that fixes this bug. Large File Support ----------------- To be able to store the size of files larger than 2GB, AIDE needs large file support (LFS) to be available in the OS. The configure script automatically checks for LFS. To turn off LFS call the configure script with the '-disable-largefile' option. Feedback and Support -------------------- End user support is available on the AIDE mailing list: https://www.ipi.fi/mailman/listinfo/aide An archive of the mailing list is available online: http://www.ipi.fi/pipermail/aide/ Please report bugs and feature requests to the aide issue tracker https://github.com/aide/aide/issues Credits ------- Please see the AUTHORS file. aide-0.19.3/config.sub0000755000175000017500000011544115137355011015722 0ustar00hvhaugwitzhvhaugwitz#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale timestamp='2024-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in cloudabi*-eabi* \ | kfreebsd*-gnu* \ | knetbsd*-gnu* \ | kopensolaris*-gnu* \ | linux-* \ | managarm-* \ | netbsd*-eabi* \ | netbsd*-gnu* \ | nto-qnx* \ | os2-emx* \ | rtmk-nova* \ | storm-chaos* \ | uclinux-gnu* \ | uclinux-uclibc* \ | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) case $field1-$field2 in # Shorthands that happen to contain a single dash convex-c[12] | convex-c3[248]) basic_machine=$field2-convex basic_os= ;; decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Do not treat sunos as a manufacturer sun*os*) basic_machine=$field1 basic_os=$field2 ;; # Manufacturers 3100* \ | 32* \ | 3300* \ | 3600* \ | 7300* \ | acorn \ | altos* \ | apollo \ | apple \ | atari \ | att* \ | axis \ | be \ | bull \ | cbm \ | ccur \ | cisco \ | commodore \ | convergent* \ | convex* \ | cray \ | crds \ | dec* \ | delta* \ | dg \ | digital \ | dolphin \ | encore* \ | gould \ | harris \ | highlevel \ | hitachi* \ | hp \ | ibm* \ | intergraph \ | isi* \ | knuth \ | masscomp \ | microblaze* \ | mips* \ | motorola* \ | ncr* \ | news \ | next \ | ns \ | oki \ | omron* \ | pc533* \ | rebel \ | rom68k \ | rombug \ | semi \ | sequent* \ | siemens \ | sgi* \ | siemens \ | sim \ | sni \ | sony* \ | stratus \ | sun \ | sun[234]* \ | tektronix \ | tti* \ | ultra \ | unicom* \ | wec \ | winbond \ | wrs) basic_machine=$field1-$field2 basic_os= ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) cpu=m68k vendor=motorola ;; # This used to be dpx2*, but that gets the RS6000-based # DPX/20 and the x86-based DPX/2-100 wrong. See # https://oldskool.silicium.org/stations/bull_dpx20.htm # https://www.feb-patrimoine.com/english/bull_dpx2.htm # https://www.feb-patrimoine.com/english/unix_and_bull.htm dpx2 | dpx2[23]00 | dpx2[23]xx) cpu=m68k vendor=bull ;; dpx2100 | dpx21xx) cpu=i386 vendor=bull ;; dpx20) cpu=rs6000 vendor=bull ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. obj= case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) saved_IFS=$IFS IFS="-" read kernel os <&2 fi ;; *) echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 exit 1 ;; esac case $obj in aout* | coff* | elf* | pe*) ;; '') # empty is fine ;; *) echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 exit 1 ;; esac # Here we handle the constraint that a (synthetic) cpu and os are # valid only in combination with each other and nowhere else. case $cpu-$os in # The "javascript-unknown-ghcjs" triple is used by GHC; we # accept it here in order to tolerate that, but reject any # variations. javascript-ghcjs) ;; javascript-* | *-ghcjs) echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os-$obj in linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ | linux-mlibc*- | linux-musl*- | linux-newlib*- \ | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) ;; uclinux-uclibc*- | uclinux-gnu*- ) ;; managarm-mlibc*- | managarm-kernel*- ) ;; windows*-msvc*-) ;; -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; -kernel*- ) echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 exit 1 ;; *-kernel*- ) echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 exit 1 ;; *-msvc*- ) echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 exit 1 ;; kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) ;; vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; nto-qnx*-) ;; os2-emx-) ;; rtmk-nova-) ;; *-eabi*- | *-gnueabi*-) ;; none--*) # None (no kernel, i.e. freestanding / bare metal), # can be paired with an machine code file format ;; -*-) # Blank kernel with real OS is always fine. ;; --*) # Blank kernel and OS with real machine code file format is always fine. ;; *-*-*) echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: aide-0.19.3/SECURITY.md0000644000175000017500000002075715032264643015541 0ustar00hvhaugwitzhvhaugwitz# Security Policy ## Supported Versions Generally the latest release (e.g. `v0.18.x`) is supported with security updates. ## Reporting a Vulnerability *PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY* If you have found a security issue in AIDE, please disclose it privately and responsibly by sending a PGP encrypted email (no HTML please) to `hannes(at)vonhaugwitz(dot)com`. You should receive a response within a few days. If for some reason you do not, please follow up via email to ensure we received your original message. Please add the address above as safe senders in your email client. Your message should include any of the following (if possible): - type of issue (e.g. buffer overflow) - affected versions - step-by-step instructions to reproduce the issue (if known) - proof-of-concept or exploit code (if available) - impact of the issue, including how an attacker might exploit the issue - your PGP key - your name and affiliation (if any), if you wish to get recognition - whether the vulnerability is public or known to third parties (if so please provide details) Encrypt your mail (preferably in `PGP/MIME` format) using the following PGP key: ``` pub rsa4096/0xF6947DAB68E7B931 2011-06-28 [C] Key fingerprint = 2BBB D30F AAB2 9B32 53BC FBA6 F694 7DAB 68E7 B931 uid [ultimate] Hannes von Haugwitz uid [ultimate] Hannes von Haugwitz sub rsa3072/0x18EE86386022EF57 2011-06-28 [S] sub rsa3072/0x57C198E495A601C7 2011-06-28 [E] sub rsa3072/0xF4B483CB268B1790 2011-06-28 [A] ``` ``` -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBE4J+9wBEADaOHrCu7XWLSs4RzDPQMv4vCdtMASJJFBzXZzxaqUaDTZpwOxR 6wMw8PFwC0UphzbX/UBSZ1Q+31Xq0sCMOBfKA4hFVY7uDwLqommVVrctlvpcKNa4 O1lov0pg7yessUnaidO+DoJ2SJW7pvvXcI6FWLXNENzsOWL8zzgIXrkU73hV3moL yrfPXwwj+tppSXeOg7HgxRSUfoqKwVkCdtQEyvBI1ue33jhwL1/9RUg4m8ph2unk QXJIloivIu7Yv0S3TgcbNzJJ7V1B/M+v1EjVKhtImp1iocxLctzE5d9G2MKfpAkg c/9McV9+KdflpS5gWZIMHHKnsJ0dzh/LZGKi47298W0h4ce3BM9gGetNyu1f7hQi 9pumoUeMymkuPeuQv3NaecLY9LSvAF9KLWRwXXxoihDYlr4cbpMyS4jT/nFCd3cu 5CXBBIoeO2w+bpxs16LD83MQdg9vRKC77sgOC/O+gWIJDh31l4aystomOOHek069 pWoOb1aIbFtaSYtVntyZ8DmyoDWvB3b/PXbxle5CkN/NPw9VDjZxqPSliTdUf1LG EDPx22fFTHfMhjgC5XqceoWWCmvqy+4grHaLSkYKimI1DlhhVH6jYnhfBzcWDb4n LyoRGOAKa0FurW5//I78wpkZCvTA4lTvJPHBI77+HlfiDjuuCMdFbyp6GQARAQAB tCxIYW5uZXMgdm9uIEhhdWd3aXR6IDxoYW5uZXNAdm9uaGF1Z3dpdHouY29tPokC VwQTAQoAQQIbAQULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAIZARYhBCu70w+qspsy U7z7pvaUfato57kxBQJoD/G1BQkeF3bZAAoJEPaUfato57kxu1YP/iOylHKonbLR 4tx6Y6U923ERO8osWeYZpd+4LeDViKGbh0d0uCxRtquz//uuiay3oyWWDiH7svb9 IXy60b9Itn2+sGX9pmMzZpnAne7xYM468Evsrxvux28oqhrP71o9ChjDo0FFmdMe l933I3j2Erb4tLiVxk9GMWhmskR8RPQXYpd6VENqxfCTVviA5dCwgdX9RnARh4mk SSthZwhaUnL/zM8rDNrVr3+UoSKestsR4Knc7US8Q00vwkVUPpTt2b40WHTdg3oS lLkpQBifj0udzBgbC72A/rDOZBS9Rr/EHEQ3YgMvEHn2Rv3nZniWwTWAdfM02To1 CNe2VxyB2k03RkC5ieI87xQ40Vr0vLZmKyQ/mjFb1bUB9RPioXVCPjXxZ8NY5a+1 4j2FPPDREtNpCJ44sdP1e8tHxmKKNV17e1JRykzmsgjRbh68vuMWLXLUHxSXP304 alFalAx3tLi7Gnpu+d5Zg+QByUZgkok1yOXhbG0b8u8G+GRb3sc48UVmQiCt6lOk a1MJ3F5GF3su6nVRMmsBlm+aZECJRsgTfDUTf/RlNF38Yu3SHlou/WOM0vaspY2/ Tg8S6qLDyXmd25LIwJdyr4Df/8xoiJCONOQOMYqedusBk0ve77MsDIx7dRGONm/o g+VSsbo7tNftWg9Up0XZ4vkcEgpgCD3dtCtIYW5uZXMgdm9uIEhhdWd3aXR6IDxo dmhhdWd3aXR6QGRlYmlhbi5vcmc+iQJUBBMBCgA+AhsBBQsJCAcDBRUKCQgLBRYC AwEAAh4BAheAFiEEK7vTD6qymzJTvPum9pR9q2jnuTEFAmgP8cIFCR4XdtkACgkQ 9pR9q2jnuTFn4w/8Djl3POjW3uQCEMpP53VydlTYRUZu+qYzdXqAQxWe3q2FDzy9 EF5dKYmMZTnSQyAP1vx4I/6CbGVUWD4E1bdG3EntoeaMojPCF+TYSvAN1dfk2iv9 a+ASa8yPhgb3bHFKHTYrBwKWlKoWlBK0X7oA217XpkAgsfYD3PzQERwWnITqOWQA NOFT+ZKQJpKifj1PjiS2ulp4NQB0G85rUDskeHo9Wx3ZPzdSZMj4JaajtIhXZGw1 RSKKAU7CMn06gI7HenpCZ3pTTAf9LZXXh9MxqhgUYU/1VYJ0VTTKM4mB3CWK/sik /oBE/j4zbsrgqeNa8hMbGk1Z1FlbqZIi3VXGi7hegkoXpC72Y157cVqnlFsP7MJl VtElrHSsc7IPuavxDa8AONqVhsU8qJb3J4be90kU4Ba+AlWxdIxdlo4p2yvmbMT9 Uz5lzZDNbRzgTrxEKoQEEa8Z1voU6QW1Xbq42jfpoIcvSMtc5yyI5ZZ/Xd1M10EI GwRJaagOCBoos28PVjc8aJWZmrRZ1R0hMf8bLvYKHZ2RWWTxkvgqjgU9z8MloZ5Z 2MA7TINxQX3NV4KTgLZNKRhA3GCAKlWO9kUCAx5utGzAaX6/tPlyvXBgYvKoMSUQ eN9K3Sdj5hBl92/2injMhEM5G2cTnUx6zwuGjWXDCFmi9cCX0jn8QTiZ0QC5AY0E Tgn8cgEMAM6Nv21neMk8LSH2HPDirz0w0UWnpkqdmk1oPCw+b4SILyJwNnOi1G5N OP9ubGLDgr1HIzVnG18k429rScgKK9gddT0dqFmmQnFvGAVaMQPTNQVZFvPiZ27j DjwupwcN5vnMlZ6Hqwk4vwTDqVi0qQ3lOnPYa9p4VLRmZO5a1A1F+CJsczifmohM nCsbcoB1iqBV3/YgQa/RW2Gqjecq/g9fmvIMgj0+O03PAp4KGizRAhcBTkebpVrR GedM9wFtn+rXNJ0PzVt0Ez2yJ+0FIKn0o/dT40h6oSDdXOce0WIW+jcAkKtpzTkf 9bleRqfRDYz2tvLbRrij1EO5POj6Z54BA/lzTCZFz9IRkrvOHyzPr6C5aP1BOJGd NhWLXNuuxykMFyoQ591qSetDFH6egnjIFaIR7TNZITew49cZi1ZcYaIEb00EdjlR 6gMzX/WOA/tptfAcaK4r8A5NnDh0cxcaGQPN9WMtcyeWIJogFFMTC07YXB13l4yU d/WfXI2l6QARAQABiQPbBBgBCgAmAhsCFiEEK7vTD6qymzJTvPum9pR9q2jnuTEF AmgP8jYFCRw2Q0QBqcDdIAQZAQgABgUCTgn8cgAKCRAY7oY4YCLvV/x3C/44CpgL VRUZT8bxDp7ZjIpyxTB43f+tpGlykSFMYS3/Cw/i7ar1fjoAeVonXAp0PpqeuJ9w +p9r3UWPZeVlmibYybLujnNDnV6RmeNtzc4HUtgPP/s7rynU6RFX46T5YRUBo/aC hjFcWVi+YUaNfBdgaKyf4INWtuNTndLXlOJkuqGCikKOuuwReJ4pvs49whVj9Nug jsotEf4/+tzsrCIWLtSF2BI/Fz0xV2vlmCzsB5fN4nC/ksaaXAL7jHwaUbTMLJ3W 9pcqBzyUd5CEMlE0bwPihyVItLLdTErbuN7M5v3iYSRakRzm0xCpyb01Ho/KWsTW znaGh3XK6e05Avss8mIaju+Zf/Vk+oLNzGqI+YAgczWyK82yDbuxXfWauBI32nmF XDwqN8pvPGGEm8BgMQxfKnV0mt3BezPTYBSuPw22+wVbao3xMJSIlIbFitw2ZOSL mit64IYYVGaWr3awn65MSK/Db9SRaGv52gOR6ylDul7wkjNE8ohlaos0y9sJEPaU fato57kxE/4P/ifW5lLtZVWKvS6pmGgDGQCEbyOIlhmPLhRdZIwUgphCkp1FEwil CECHy3j+aBSRTHP8J+83LO+3V5DI2PO37JfEyBxKIzTAkoX3wu9NJtGQDmDv/Bc+ J3EpmfW6CtoWTn6bXAzIqCN7YxTWqNY4UKafovzm+wV5X6h04VK4qjzqwsRMUECr H/KNfiuj2L9ytB0DkSSKR9YK0VaDgOP91ybUVoOtVYhECSja6M9Ebno+UG5FuNnS ktbpWWwrmW9VR2GOQtmkPak+QKpGjJ3GZA+2HJ81kEwtg9qpIkWrlWtD3HkWjv6p DR0K+JXs4zd6DaMBUrUkR2JqO5jnYCsDGI2LB01WdODuTs6YqIiM9pvn8loSvjCU 6tyH9kZRpcU2qddoCFeeQdRUbAhCyqULtgGARZJmFiW6owrIMNbpr/f1CuHyUhfx kV8dm+ebvarzf/WYbUXRi9ZY+j7Qm8AvhgCkudbISOOe9RXok5b6NG4W+owuB+4+ vcmVfV7/ATaVTXuCUZ5x5Xuq4TlQB6R11eKrz0RUWBYU3PJV+B96DpIdxcPzfYOR t9E+nlglpHGjCGxQmhYmZhskZPQl7pnE/l+/tK8iwD6/djvMvtkkoVLqVWHwusoi 6sgDop7YHtaChNEP5dJL1DsVlHnaXsSak1d0hTsbiiqKKlm/OZRl0e9yuQGNBE4J /TQBDACoLGAOK8w/Mv1B3SZN/mfUYXgjJnOS1lqCNdKRG8MVQQCBVEe9QPU8yavh /MpraEvPZhz6WSg7k1pHNMbKsDfv80ZX5WM95uMN69nmF/l+qo+eBJU8YIHWabkv MSWTBeD1roo8CwHOl102ajgo0XzhCqeb4MkUCZCZxdTaoHcD+IW+4IbajozgzTYV EQnyJdZwmB/EjRAncKDNCDoimHzjENQ9KOO/cPoGTFNfy9czoAmOY8gWt7b4wELD Mx/tP06V3n9Zjpxx+sBId9xDv+Yd+JSJHbNk8FxQtRtZVGNv7SP0rIWv3AP+d93k t/djtijzFTS5JxFViJtjwsDMdXQYnb+ReP4Jza5gLr/8gjbCRlLv/Bh1D9SyXFmf tEcZyhJIUU2b2ybdCkwg/BdouoQxHN94bESy686djt1wiXLZa6s4jiFuMA3qfF+K HDIbdjMBZzi0+XgJwwiqLlRkvLiG8/mGCijwFY+zzZ2lxKCOAEo8bUexOBz16Sw1 Fj55vgsAEQEAAYkCPAQYAQoAJgIbDBYhBCu70w+qspsyU7z7pvaUfato57kxBQJo D/JdBQkcNkKpAAoJEPaUfato57kxSEgP/j2W0lozGOBH5UdR6COHrCR5uxlXNy+n XzP7vJBcfs2vm47SGYJrOcCQBuUD2vtbt2AaPV21MJAWmfVKja1/OwUtOnsOQZnd x+e1YS4s8IfUR18CAla1VqRoLepG+T0XsQ8Sf5Zny24FNHaSFFn46vx9DIsgKV7n Jrt8SjP0cisLN3A4CjDMI7qBfdDuIA5IH1SEB+Wiq3wbh50vm4H/sraEmzBTGl6Y QPGvMmLg51vheyRwIQ+EIedXqgERBiyRbmyauOch9r0htOpP8cGbF+R39xucZMdn 4QMM+ixDE04khVL6QZtBG7YVufK6J/vBlGliuTojBQTYRqIVDK8qhEUGt7ffak98 Q2k/FC0QC95wo84IYWcucKL1UKk6xLreLja98qwvS/uYxBO/gA//HVZw08J+W/UL j0/CIc+Jbx0NwdRrubbWT6CbPKB8b+NFMhzre3sx/q33l+O32gbZaMHAG9CRcB7A g7NGNGNlBv9Y9PmiwjxrTqx1RV02oHKpkjS1q4Cn8ko5ZHi+RtfLHt2nH7RC4trQ Jh1yr7NF3L9RtegndmwKaGxTW65HJxrUzaXERcAMXezaJmOU4kGSgOiruyzdq0rp 75kx2/GNNLQ/2iQFhxZ5MN8t/WPjPEJ2N7tzcCOuDVkw1R1qPkZiuFOArjcwF9q4 bDkkUSqzSREduQGNBE4J/a0BDADFSeNMstJh2Sx8LlLxTVoBVSPdm2G15kBsikDG pWN4LiscKQT4Rmzi0uBuA1z+kD+eA+4G2nCqM7xO0RJAPLQi2zcfehdrbdwDBsFb eCTe2lnbLqGodn0ff7YDlCyopKszgINOQQwXr4VSqG7cOGDGC38taaX5UBR7XJs0 DMb4Hg0Oer7kN3kfSnOwihfS9lgunFIp3dNN1iUEp1NAVOyJhS//4zGh5EYiTd7y QYQC21H6eiJTmnnvLm/nskiBeR4RFm8ozGAizcji+qwjR1AeeM7ifoIxtuVFH23A Y7KGzId4y4Bh+Ni8uQO1eTGcc2XITAj5oFdYdC61wJ3B2i1w24gAYNqAJ8bodnYA JatFRncuaYT6X5bNKHGT+u4KqedR55njEP7XxkXyfL06gI4ri1ef22d8X0kJIY3d d2LD81qGfAEU8Q/qboPdeaVEtG0FfMCTqQ1yyct1jkbKZMUK/EPompgUZb6JTQov bRGUPZFbhpq8nVAsu+jRRPVFzmkAEQEAAYkCPAQYAQoAJgIbIBYhBCu70w+qspsy U7z7pvaUfato57kxBQJoD/JqBQkcNkI9AAoJEPaUfato57kxsHIP/idmkMDpHyBp 1G+9Z/JMxbbAXqKtM1VecPi9ptUtKUL1rGg1iMFUX/E+Sdihw7QkjSWa+l1ANRRD bMF9xvLgBjHkcp3YJ2gcaUQ1S3SihftqlA1rXYhD4ZkRxRQQmGdV2ueS1QZJuc0P QRq/63D9lw72nSiuuXLprtU86THncfwJVLPc+Q62MrvmLA6yInczsXjhhBzfdiie rqIwfWQAZw0C3sg9C5vjIFYscbMa1Y9AggCtWyRenJJiPvBE0nkwMVZMA7TxFi0h SiBjRacdBy2BN5HyXLOHP+Lgb8fSxYEKAozJ5YzzfqJjPsNpt7GukxVeQrsRCvRi FDmYHHgm/TZZ8+ilzrJnFGd0Ikazh8K5nOQo5DUBeBDreNcSPRHHFLqShm/Unhb5 uESyClCSm745w/zJ4JFA+bxaP64HbnkT9ceERmeKvh+pHXFmhBUPyWLlquTyhCnu mDG7A71OUsqayVswuN2fz09cfbVXdVJg1wGtDHdXbywSrlLxv4Y5Gn4mczkYqMhU lt8iCQHoQKRKtuZEUEBbpLiOl21CEKX0PXsg6qB/Uij3jaZ3PIfDpWa14HnVV4Ro eP0X7uYO+T8LmU97AZgVB/nKIWtuXu+E03RpZqwVbtR5XZUYOzadSha9uYYpUj4x UDPDXVVv4sGio8wU3lSJRhp2U4W96PEU =CF3r -----END PGP PUBLIC KEY BLOCK----- ``` aide-0.19.3/tests/0000755000175000017500000000000015137355021015074 5ustar00hvhaugwitzhvhaugwitzaide-0.19.3/tests/check_aide.c0000644000175000017500000000271314774422002017302 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2019,2024 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "check_aide.h" #include "hashsum.h" #include "log.h" int main (void) { int number_failed; SRunner *sr; init_hashsum_lib(); sr = srunner_create (make_attributes_suite()); srunner_add_suite(sr, make_base64_suite()); srunner_add_suite(sr, make_progress_suite()); srunner_add_suite(sr, make_seltree_suite()); srunner_add_suite(sr, make_hashsum_suite()); set_log_level(LOG_LEVEL_DEBUG); set_colored_log(false); srunner_run_all (sr, CK_NORMAL); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } aide-0.19.3/tests/check_hashsum.c0000644000175000017500000002004114774422002020042 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2024,2025 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "attributes.h" #include "hashsum.h" #include "md.h" #include "util.h" typedef struct { size_t size; char expected[num_hashes][128 + 1]; } hashsum_test_t; static char *message = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; static hashsum_test_t hashsum_tests[] = { { .size = 0, .expected = { "d41d8cd98f00b204e9800998ecf8427e", /* md5 */ "da39a3ee5e6b4b0d3255bfef95601890afd80709", /* sha1 */ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", /* sha256 */ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", /* sha512 */ "9c1185a5c5e9fc54612808977ee8f548b2258d31", /* rmd160 */ "24f0130c63ac933216166e76b1bb925ff373de2d49584e7a", /* tiger */ "00000000", /* crc32 */ "00000000", /* crc32b */ "4f6938531f0bc8991f62da7bbd6f7de3fad44562b8c6f4ebf146d5b4e46f7c17", /* haval */ "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", /* whirlpool */ "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d", /* gost */ "3f539a213e97c802cc229d474c6aa32a825a360b2a933a949fd925208d9ce1bb", /* stribog256 */ "8e945da209aa869f0455928529bcae4679e9873ab707b55315f56ceb98bef0a7362f715528356ee83cda5f2aac4c6ad2ba3a715c1bcd81cb8e9f90bf4c1c1a8a", /* stribog512 */ "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", /* sha512_256 */ "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", /* sha3-256 */ "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", /* sha3-512 */ } }, { .size = 12, .expected = { "2b0dc568e588e46a5a7cd56dcec348af", /* md5 */ "2aa36a1111059c0bbd7ad0c6bba108f50df8e867", /* sha1 */ "922429ccdb7045d11143e2e3982a11afc11b537bf259d88d2425fa8806e86e78", /* sha256 */ "5d8b766d3b37ce8aa68dd354a50af9c94201286d7993d42e20bb7a93c0cc9897fd2714a2860ec8c4d79912376c8234dfb52e841eff0eb960370a84ea5735e8b3", /* sha512 */ "14d3deb9667ab31c0f76a57ef5055f29f4bc432e", /* rmd160 */ "0c26dd2215a6d6168ece5bce5a8d02afcfcd57c4759da8e5", /* tiger */ "634a5234", /* crc32 */ "34524a63", /* crc32b */ "3e3ae002124d7fabd23b04e596bbaab7760ad02b9d46ae761a724c3a0751e143", /* haval */ "8535c1b311244a56aba746411d74b1a2bafe1238983def9da7aaa61e3e80d365ab00d7be6753341b45ade19d858d2b9f8a0cf27a5a7b2ff77952b8a780d8d587", /* whirlpool */ "5ecd800c05dea7b6badd7aba7e329c7aca5b42e38784b6a0efb83bd65a7c50ec", /* gost */ "c367afdb2a05726b46f82e1cd32d6a8cb06c7a03b5cebfc94df0d1a4153e90af", /* stribog256 */ "f4d24b77221fe6734eaefe2c85899ba7dc66f88be0fbde61f4a9e34198f606501ac67ad246d0f44e4722b42c5837d0c0af5e0a32d3f891ee8dd90e6dceef7f9b", /* stribog512 */ "e39ab44f3128533b5a3092a13c6de7e759f0d048a58df860fe3d9d5341e1b507", /* sha512_256 */ "d99428764cc43a2ff5c1ac4db1e5da826a97dae5530e268650318adb2e2e246f", /* sha3-256 */ "644f8950457497a7ad3b89ff1bae0d5104604dfe7191b95fed4750a551bb0705173fba66cb71bac5e89dbef418096a76f74db060298c3e2ab54a3513fe50b9ea", /* sha3-512 */ } }, { .size = 62, .expected = { "bef25ba0f6a4d8f8ec8d5d5122241a10", /* md5 */ "bb814cf15cf9478829e6b85205824b0f1fd8ca08", /* sha1 */ "4931ea748296a1cd4fed8cf6275ecb0f2df8e11bafa9457b9ab62c47bc0bc2df", /* sha256 */ "509fdf28fefbc5ef33e88ef0b239115ab620ed1e94a7adf95549b03f23359c9a38131ad8056957c279e8f74b9c23feba57bd6501bb2d06546398242079fefbb7", /* sha512 */ "93a67b62a5e060ef799259c41430c49f9a4e0a10", /* rmd160 */ "266b9f823d34ec3acf51ce37f28040f885cd24494c9a682b", /* tiger */ "9f5b8ff1", /* crc32 */ "f18f5b9f", /* crc32b */ "46d100b49ce74d6a1a02af140f3720d9d65bde7342b36ca3c92fcf893451f021", /* haval */ "fc63bb82de354304a63af835e2596136639f365aec5be609a4a1264fa496c4a5eadb3d615d9f9c06f3aa9eb4654780b461b51b79ad25a15aebe1033babc120c8", /* whirlpool */ "8fd10ed0d94fbacef168095b733cc82ba091e98f1947b12cb46090dafa345150", /* gost */ "82985767032f0a24c7b0be97daf3fde20b0a26c58ba0fc629488f0006b061c05", /* stribog256 */ "11115c0e8f26b6c9ad6b94f04c7fb4269c32c9ef841c10068df1f0a0f031df3b010bcbd6442e1f4ac35ea50e5a01f96e1a196ae9654da51cb7dec4daf22aed23", /* stribog512 */ "f288ffd88561cb7fa728dbaa80fe195016a188959be61f1c297826fec2a11864", /* sha512_256 */ "4d877e02ff6f9ffdf4fe894a5814fb8836db7b1e18f8c94788cf8144d6eca616", /* sha3-256 */ "15b6d95c749b322c9d91e92bc5498cdabe0919fb7a7d3d7f9940092077e61370f96b46079b4858ee14906c929d0217acaf58d3fa8c2d622b29a95dd643978cd6", /* sha3-512 */ } }, }; static int num_hashsum_tests = sizeof hashsum_tests / sizeof(hashsum_test_t); START_TEST(test_hashsum) { char *dummy_filename = ""; md_hashsums md; struct md_container mdc; mdc.todo_attr = get_hashes(false); init_md(&mdc, dummy_filename, NULL); update_md(&mdc, message, hashsum_tests[_i].size); close_md(&mdc, &md, dummy_filename, NULL); for (int i = 0; i < num_hashes; ++i) { if (algorithms[i] >= 0) { char *hashsum = byte_to_base16(md.hashsums[i], hashsums[i].length); ck_assert_msg(stricmp(hashsum, hashsum_tests[_i].expected[i]) == 0, "\n" "%10s hashsum retruned: %s\n" " expected: %s", attributes[hashsums[i].attribute].config_name, hashsum, hashsum_tests[_i].expected[i]); free(hashsum); } } } END_TEST Suite *make_hashsum_suite(void) { Suite *s = suite_create("hashsum"); TCase *tc_hashsum = tcase_create("hashsum"); tcase_add_loop_test(tc_hashsum, test_hashsum, 0, num_hashsum_tests); suite_add_tcase(s, tc_hashsum); return s; } aide-0.19.3/tests/check_progress.c0000644000175000017500000002561214774422002020247 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2024 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "util.h" typedef struct { char * path; long unsigned entries; long unsigned skipped; int length; const char *expected_string; } progress_test_t; static progress_test_t progress_tests[] = { { NULL, 0, 0, 50, "[00:01] scan file system> 0 files" }, { NULL, 0, 0, 40, "[00:01] scan file system> 0 files" }, { NULL, 0, 0, 33, "[00:01] scan file system> 0 files" }, { NULL, 0, 0, 30, "[00:01] scan file system> 0 fi" }, { NULL, 0, 0, 20, "[00:01] scan file sy" }, { NULL, 0, 0, 10, "[00:01] sc" }, { NULL, 0, 0, 5, "[00:0" }, { NULL, 0, 0, 1, "[" }, { NULL, 0, 1230, 60, "[00:01] scan file system> 0 files (1230 skipped)" }, { NULL, 0, 1230, 50, "[00:01] scan file system> 0 files (1230 skipped)" }, { NULL, 0, 1230, 48, "[00:01] scan file system> 0 files (1230 skipped)" }, { NULL, 0, 1230, 40, "[00:01] scan file system> 0 files (1230 " }, { NULL, 0, 1230, 30, "[00:01] scan file system> 0 fi" }, { NULL, 0, 1230, 20, "[00:01] scan file sy" }, { NULL, 0, 1230, 10, "[00:01] sc" }, { NULL, 0, 1230, 5, "[00:0" }, { NULL, 0, 1230, 1, "[" }, { "/etc/fstab", 1, 0, 60, "[00:01] scan file system> 1 file, last /etc/fstab" }, { "/etc/fstab", 1, 0, 50, "[00:01] scan file system> 1 file, last /etc/fstab" }, { "/etc/fstab", 1, 0, 49, "[00:01] scan file system> 1 file, last /etc/fstab" }, { "/etc/fstab", 1, 0, 43, "[00:01] scan file system> 1 file, last /etc" }, { "/etc/fstab", 1, 0, 40, "[00:01] scan file system> 1 file, last /" }, { "/etc/fstab", 1, 0, 30, "[00:01] scan file system> 1 fi" }, { "/etc/fstab", 1, 0, 20, "[00:01] scan file sy" }, { "/etc/fstab", 1, 0, 10, "[00:01] sc" }, { "/etc/fstab", 1, 0, 5, "[00:0" }, { "/etc/fstab", 1, 0, 1, "[" }, { "/", 3100, 12310, 70, "[00:01] scan file system> 3100 files (12310 skipped), last /" }, { "/", 3100, 12310, 60, "[00:01] scan file system> 3100 files (12310 skipped), last /" }, { "/", 3100, 12310, 50, "[00:01] scan file system> 3100 files (12310 skippe" }, { "/", 3100, 12310, 40, "[00:01] scan file system> 3100 files (12" }, { "/", 3100, 12310, 30, "[00:01] scan file system> 3100" }, { "/", 3100, 12310, 20, "[00:01] scan file sy" }, { "/", 3100, 12310, 10, "[00:01] sc" }, { "/", 3100, 12310, 5, "[00:0" }, { "/", 3100, 12310, 1, "[" }, { "/system", 3100, 12310, 80, "[00:01] scan file system> 3100 files (12310 skipped), last /system" }, { "/system", 3100, 12310, 70, "[00:01] scan file system> 3100 files (12310 skipped), last /system" }, { "/system", 3100, 12310, 66, "[00:01] scan file system> 3100 files (12310 skipped), last /system" }, { "/system", 3100, 12310, 63, "[00:01] scan file system> 3100 files (12310 skipped), last /sys" }, { "/system", 3100, 12310, 60, "[00:01] scan file system> 3100 files (12310 skipped), last /" }, { "/system", 3100, 12310, 50, "[00:01] scan file system> 3100 files (12310 skippe" }, { "/system", 3100, 12310, 40, "[00:01] scan file system> 3100 files (12" }, { "/system", 3100, 12310, 30, "[00:01] scan file system> 3100" }, { "/system", 3100, 12310, 20, "[00:01] scan file sy" }, { "/system", 3100, 12310, 10, "[00:01] sc" }, { "/system", 3100, 12310, 5, "[00:0" }, { "/system", 3100, 12310, 1, "[" }, { "/etc/fstab", 100, 10, 80, "[00:01] scan file system> 100 files (10 skipped), last /etc/fstab" }, { "/etc/fstab", 100, 10, 70, "[00:01] scan file system> 100 files (10 skipped), last /etc/fstab" }, { "/etc/fstab", 100, 10, 65, "[00:01] scan file system> 100 files (10 skipped), last /etc/fstab" }, { "/etc/fstab", 100, 10, 60, "[00:01] scan file system> 100 files (10 skipped), last /etc/" }, { "/etc/fstab", 100, 10, 50, "[00:01] scan file system> 100 files (10 skipped), " }, { "/etc/fstab", 100, 10, 40, "[00:01] scan file system> 100 files (10 " }, { "/etc/fstab", 100, 10, 30, "[00:01] scan file system> 100 " }, { "/etc/fstab", 100, 10, 20, "[00:01] scan file sy" }, { "/etc/fstab", 100, 10, 10, "[00:01] sc" }, { "/etc/fstab", 100, 10, 5, "[00:0" }, { "/etc/fstab", 100, 10, 1, "[" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 130, "[00:01] scan file system> 6393 files (230 skipped), last /usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 129, "[00:01] scan file system> 6393 files (230 skipped), last /usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 120, "[00:01] scan file system> 6393 files (230 skipped), last /usr/.../device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 110, "[00:01] scan file system> 6393 files (230 skipped), last /usr/.../libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 100, "[00:01] scan file system> 6393 files (230 skipped), last /usr/.../libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 90, "[00:01] scan file system> 6393 files (230 skipped), last /usr/.../libdevmapper-event-lvm2m" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 80, "[00:01] scan file system> 6393 files (230 skipped), last /usr/.../libdevmapper-e" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 70, "[00:01] scan file system> 6393 files (230 skipped), last /usr/.../libd" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 60, "[00:01] scan file system> 6393 files (230 skipped), last /us" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 50, "[00:01] scan file system> 6393 files (230 skipped)" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 40, "[00:01] scan file system> 6393 files (23" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 30, "[00:01] scan file system> 6393" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 20, "[00:01] scan file sy" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 10, "[00:01] sc" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 5, "[00:0" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 6393, 230, 1, "[" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 120, "[00:01] scan file system> 1 file, last /usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 111, "[00:01] scan file system> 1 file, last /usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 110, "[00:01] scan file system> 1 file, last /usr/.../device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 100, "[00:01] scan file system> 1 file, last /usr/.../device-mapper/libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 90, "[00:01] scan file system> 1 file, last /usr/.../libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 80, "[00:01] scan file system> 1 file, last /usr/.../libdevmapper-event-lvm2mirror.so" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 70, "[00:01] scan file system> 1 file, last /usr/.../libdevmapper-event-lvm" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 60, "[00:01] scan file system> 1 file, last /usr/.../libdevmapper" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 50, "[00:01] scan file system> 1 file, last /usr/.../li" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 40, "[00:01] scan file system> 1 file, last /" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 30, "[00:01] scan file system> 1 fi" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 20, "[00:01] scan file sy" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 10, "[00:01] sc" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 5, "[00:0" }, { "/usr/lib/x86_64-linux-gnu/device-mapper/libdevmapper-event-lvm2mirror.so", 1, 0, 1, "[" }, }; static int num_diff_progress_tests = sizeof progress_tests / sizeof(progress_test_t); START_TEST (get_progress_bar_string_test) { char *str = get_progress_bar_string("scan file system", progress_tests[_i].path, progress_tests[_i].entries, progress_tests[_i].skipped, 1, progress_tests[_i].length); ck_assert_msg(strcmp(progress_tests[_i].expected_string, str) == 0, "\n" "get_progress_bar_string(path: '%s', entries: %lu, skipped: %lu, length: %d):\n" " string returned '%s'\n" " expected '%s'", progress_tests[_i].path, progress_tests[_i].entries, progress_tests[_i].skipped, progress_tests[_i].length, str, progress_tests[_i].expected_string); free(str); } END_TEST Suite *make_progress_suite(void) { Suite *s = suite_create ("progress"); TCase *tc_get_progress_bar_string = tcase_create ("get_progress_bar_string"); tcase_add_loop_test (tc_get_progress_bar_string, get_progress_bar_string_test, 0, num_diff_progress_tests); suite_add_tcase (s, tc_get_progress_bar_string); return s; } aide-0.19.3/tests/check_attributes.c0000644000175000017500000001006514412055402020560 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2019-2020 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "attributes.h" typedef struct { DB_ATTR_TYPE a; DB_ATTR_TYPE b; const char *expected_string; } diff_attributes_t; static diff_attributes_t diff_attributes_tests[] = { { 0, 0, "" }, /* { 0, ATTR(attr_filename), "filename" }, */ { 0, ATTR(attr_linkname), "l" }, { 0, ATTR(attr_perm), "p" }, { 0, ATTR(attr_uid), "u" }, { 0, ATTR(attr_gid), "g" }, { 0, ATTR(attr_size), "s" }, { 0, ATTR(attr_atime), "a" }, { 0, ATTR(attr_ctime), "c" }, { 0, ATTR(attr_mtime), "m" }, { 0, ATTR(attr_inode), "i" }, { 0, ATTR(attr_bcount), "b" }, { 0, ATTR(attr_linkcount), "n" }, { 0, ATTR(attr_md5), "md5" }, { 0, ATTR(attr_sha1), "sha1" }, { 0, ATTR(attr_rmd160), "rmd160" }, { 0, ATTR(attr_tiger), "tiger" }, { 0, ATTR(attr_crc32), "crc32" }, { 0, ATTR(attr_haval), "haval" }, { 0, ATTR(attr_gostr3411_94), "gost" }, { 0, ATTR(attr_crc32b), "crc32b" }, /* { 0, ATTR(attr_attr), "attr" }, */ { 0, ATTR(attr_acl), "acl" }, /* { 0, ATTR(attr_bsize), "bsize" }, */ /* { 0, ATTR(attr_rdev), "rdev" }, */ /* { 0, ATTR(attr_dev), "dev" }, */ /* { 0, ATTR(attr_allhashsums), "H" }, */ { 0, ATTR(attr_sizeg), "S" }, { 0, ATTR(attr_checkinode), "I" }, { 0, ATTR(attr_allownewfile) , "ANF" }, { 0, ATTR(attr_allowrmfile), "ARF" }, { 0, ATTR(attr_sha256), "sha256" }, { 0, ATTR(attr_sha512), "sha512" }, { 0, ATTR(attr_selinux), "selinux" }, { 0, ATTR(attr_xattrs), "xattrs" }, { 0, ATTR(attr_whirlpool), "whirlpool" }, { 0, ATTR(attr_ftype), "ftype" }, { 0, ATTR(attr_e2fsattrs), "e2fsattrs" }, { 0, ATTR(attr_capabilities), "caps" }, { 0, ATTR(attr_linkname)|ATTR(attr_perm), "l+p" }, { 0, ATTR(attr_ctime)|ATTR(attr_ftype), "c+ftype" }, { 0, ATTR(attr_linkname)|ATTR(attr_perm)|ATTR(attr_uid)|ATTR(attr_gid)|ATTR(attr_size)|ATTR(attr_bcount)|ATTR(attr_linkcount)|ATTR(attr_sha256)|ATTR(attr_tiger)|ATTR(attr_haval)|ATTR(attr_sha512)|ATTR(attr_ftype), "l+p+u+g+s+b+n+tiger+haval+sha256+sha512+ftype" }, { ATTR(attr_linkname), 0 , "-l" }, { ATTR(attr_linkname), ATTR(attr_linkname) , "" }, { ATTR(attr_linkname), ATTR(attr_linkname)|ATTR(attr_perm) , "+p" }, { ATTR(attr_linkname)|ATTR(attr_perm), ATTR(attr_linkname) , "-p" }, { ATTR(attr_perm)|ATTR(attr_mtime), ATTR(attr_perm)|ATTR(attr_uid)|ATTR(attr_gid)|ATTR(attr_size)|ATTR(attr_bcount)|ATTR(attr_linkcount), "+u+g+s-m+b+n" }, }; static int num_diff_attributes_tests = sizeof diff_attributes_tests / sizeof(diff_attributes_t); START_TEST (test_diff_attributes) { char *str = diff_attributes(diff_attributes_tests[_i].a, diff_attributes_tests[_i].b); ck_assert_msg(strcmp(diff_attributes_tests[_i].expected_string, str) == 0, "diff_attributes: %llu %llu: string returned '%s' != '%s'", diff_attributes_tests[_i].a, diff_attributes_tests[_i].b, str, diff_attributes_tests[_i].expected_string); free(str); } END_TEST Suite *make_attributes_suite(void) { Suite *s = suite_create ("attributes"); TCase *tc_diff_attributes = tcase_create ("diff_attributes"); tcase_add_loop_test (tc_diff_attributes, test_diff_attributes, 0, num_diff_attributes_tests); suite_add_tcase (s, tc_diff_attributes); return s; } aide-0.19.3/tests/check_base64.c0000644000175000017500000000510214774422002017457 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2024 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "base64.h" typedef struct { char* orig; char* base64; } base64_t; static base64_t base64_tests[] = { { "A", "QQ==" }, { "AA", "QUE=" }, { "AAA", "QUFB" }, { "AAAA", "QUFBQQ==" }, { "AAAAA", "QUFBQUE=" }, { "AAAAAA", "QUFBQUFB" }, { "AAAAAAA", "QUFBQUFBQQ==" }, { "AAAAAAA", "QUFBQUFBQQ==" }, }; static int num_base64_tests = sizeof base64_tests / sizeof(base64_t); START_TEST (test_base64) { size_t orig_length = strlen(base64_tests[_i].orig); char *base64 = encode_base64((byte *) base64_tests[_i].orig, orig_length); ck_assert_msg(strcmp(base64_tests[_i].base64, base64) == 0, "\n" "encode_base64('%s', %zu ):\n" "string returned '%s'\n" " expected '%s'", base64_tests[_i].orig, orig_length, base64, base64_tests[_i].base64); size_t orig_length_pointer; size_t base64_length = strlen(base64); byte *orig = decode_base64(base64, base64_length, &orig_length_pointer); ck_assert_msg(strcmp(base64_tests[_i].orig, (char *) orig) == 0, "\n" "padded decode_base64('%s', %zu ):\n" "string returned '%s'\n" " expected '%s'", base64, base64_length, orig, base64_tests[_i].orig); ck_assert_msg(orig_length_pointer == orig_length, "padded decode_base64(' %s', %zu) returned length %zu (expected: %zu)", base64, base64_length, orig_length_pointer, orig_length); free(orig); free(base64); } END_TEST Suite *make_base64_suite(void) { Suite *s = suite_create ("base64"); TCase *tc_base64 = tcase_create ("base64"); tcase_add_loop_test (tc_base64, test_base64, 0, num_base64_tests); suite_add_tcase (s, tc_base64); return s; } aide-0.19.3/tests/check_seltree.c0000644000175000017500000012514114774422002020044 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2024,2015 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "seltree.h" #include "rx_rule.h" #include "log.h" #include "file.h" typedef struct { char *regex; AIDE_RULE_TYPE type; rx_restriction_t restriction; } check_seltree_rule_t; typedef struct { file_t file; match_result expected_match; } check_seltree_test_t; static seltree *add_rules(check_seltree_rule_t rules[], size_t num_of_rules) { seltree *tree = init_tree(); char* node_path = NULL; for (size_t i = 0 ; i < num_of_rules ; i++) { add_rx_to_tree(rules[i].regex, rules[i].restriction, rules[i].type, tree, i, "check_seltree", "n/a", &node_path); } log_tree(LOG_LEVEL_RULE, tree, 0); return tree; } static void test_rules(seltree *tree, check_seltree_test_t tests[], size_t num_of_tests) { for (size_t i = 0 ; i < num_of_tests ; i++) { log_msg(LOG_LEVEL_RULE, "\u252c check '%s' (filetype: %c)", tests[i].file.name, get_f_type_char_from_f_type(tests[i].file.type)); match_t match = check_seltree(tree, tests[i].file, true, NULL); log_msg(LOG_LEVEL_RULE, "\u2534 result: %s", get_match_result_string(match.result)); ck_assert_msg(tests[i].expected_match == match.result , "check_seltree %s (f_type: %c): returned %s (%d) (expected: %s (%d))", tests[i].file.name, get_f_type_char_from_f_type(tests[i].file.type), get_match_result_string(match.result), match.result, get_match_result_string(tests[i].expected_match), tests[i].expected_match); } } START_TEST (test_unrestricted_equal_rule) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_equal_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_EQUAL_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_EQUAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_equal_rule_slash) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_equal_rule_slash"); check_seltree_rule_t rules[] = { { .regex = "/dev/", .type = AIDE_EQUAL_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_EQUAL_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_EQUAL_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_recursive_negative_rule_eol) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_recursive_negative_rule_eol"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_recursive_negative_rule) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_recursive_negative_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_non_recursive_negative_rule_eol) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_non_recursive_negative_rule_eol"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_non_recursive_negative_rule) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_non_recursive_negative_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_recursive_negative_rule_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_recursive_negative_rule_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_recursive_negative_rule_eol_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_recursive_negative_rule_eol_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_non_recursive_negative_rule_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_non_recursive_negative_rule_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_non_recursive_negative_rule_eol_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_non_recursive_negative_rule_eol_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_deep_selective_rule) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_deep_selective_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev/.*/[0-9]", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/etc/deep/down/0", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_unrestricted_forbid_root) { log_msg(LOG_LEVEL_INFO, "test_unrestricted_forbid_root"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, { .regex = "/", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_equal_rule) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_equal_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_EQUAL_RULE, .restriction = { .f_type = FT_DIR } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_EQUAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_equal_rule_slash) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_equal_rule_slash"); check_seltree_rule_t rules[] = { { .regex = "/dev/", .type = AIDE_EQUAL_RULE, .restriction = { .f_type = FT_DIR } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_EQUAL_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_recursive_negative_rule_eol) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_recursive_negative_rule_eol"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_recursive_negative_rule) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_recursive_negative_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_non_recursive_negative_rule_eol) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_non_recursive_negative_rule_eol"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_restricted_recursive_negative_rule_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_restricted_recursive_negative_rule_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_restricted_recursive_negative_rule_eol_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_restricted_recursive_negative_rule_eol_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_restricted_non_recursive_negative_rule_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_restricted_non_recursive_negative_rule_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_restricted_non_recursive_negative_rule_eol_deep_selective) { log_msg(LOG_LEVEL_INFO, "test_restricted_non_recursive_negative_rule_eol_deep_selective"); check_seltree_rule_t rules[] = { { .regex = "/dev$", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/dev/pts", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NO_RULE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NO_RULE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_non_recursive_negative_rule) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_non_recursive_negative_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, { .regex = "/", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_NULL } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_deep_selective_rule) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_deep_selective_rule"); check_seltree_rule_t rules[] = { { .regex = "/dev/.*/[0-9]", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_BLK } }, { .regex = "/etc/deep/down/0", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_REG } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_BLK }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_SELECTIVE_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_PARTIAL_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_SELECTIVE_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST START_TEST (test_f_type_restricted_forbid_root) { log_msg(LOG_LEVEL_INFO, "test_f_type_restricted_forbid_root"); check_seltree_rule_t rules[] = { { .regex = "/dev", .type = AIDE_SELECTIVE_RULE, .restriction = { .f_type = FT_BLK } }, { .regex = "/", .type = AIDE_NON_RECURSIVE_NEGATIVE_RULE, .restriction = { .f_type = FT_DIR } }, }; check_seltree_test_t tests[] = { { (file_t){ .name = "/", .type = FT_DIR }, .expected_match = RESULT_NON_RECURSIVE_NEGATIVE_MATCH }, { (file_t){ .name = "/dev", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/sda", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/0", .type = FT_BLK }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/dev/pts/deep/down/0", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc", .type = FT_DIR }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, { (file_t){ .name = "/etc/deep/down/0", .type = FT_REG }, .expected_match = RESULT_NEGATIVE_PARENT_MATCH }, }; test_rules(add_rules(rules, sizeof(rules)/sizeof(check_seltree_rule_t)), tests, sizeof(tests)/sizeof(check_seltree_test_t)); } END_TEST Suite *make_seltree_suite(void) { Suite *s = suite_create ("seltree"); TCase *tc_check_seltree = tcase_create ("check_seltree"); tcase_add_test(tc_check_seltree, test_unrestricted_equal_rule); tcase_add_test(tc_check_seltree, test_unrestricted_equal_rule_slash); tcase_add_test(tc_check_seltree, test_unrestricted_recursive_negative_rule_eol); tcase_add_test(tc_check_seltree, test_unrestricted_recursive_negative_rule); tcase_add_test(tc_check_seltree, test_unrestricted_non_recursive_negative_rule_eol); tcase_add_test(tc_check_seltree, test_unrestricted_non_recursive_negative_rule); tcase_add_test(tc_check_seltree, test_unrestricted_recursive_negative_rule_deep_selective); tcase_add_test(tc_check_seltree, test_unrestricted_recursive_negative_rule_eol_deep_selective); tcase_add_test(tc_check_seltree, test_unrestricted_non_recursive_negative_rule_deep_selective); tcase_add_test(tc_check_seltree, test_unrestricted_non_recursive_negative_rule_eol_deep_selective); tcase_add_test(tc_check_seltree, test_unrestricted_deep_selective_rule); tcase_add_test(tc_check_seltree, test_unrestricted_forbid_root); tcase_add_test(tc_check_seltree, test_f_type_restricted_equal_rule); tcase_add_test(tc_check_seltree, test_f_type_restricted_equal_rule_slash); tcase_add_test(tc_check_seltree, test_f_type_restricted_recursive_negative_rule_eol); tcase_add_test(tc_check_seltree, test_f_type_restricted_recursive_negative_rule); tcase_add_test(tc_check_seltree, test_f_type_restricted_non_recursive_negative_rule_eol); tcase_add_test(tc_check_seltree, test_f_type_restricted_non_recursive_negative_rule); tcase_add_test(tc_check_seltree, test_restricted_recursive_negative_rule_deep_selective); tcase_add_test(tc_check_seltree, test_restricted_recursive_negative_rule_eol_deep_selective); tcase_add_test(tc_check_seltree, test_restricted_non_recursive_negative_rule_deep_selective); tcase_add_test(tc_check_seltree, test_restricted_non_recursive_negative_rule_eol_deep_selective); tcase_add_test(tc_check_seltree, test_f_type_restricted_deep_selective_rule); tcase_add_test(tc_check_seltree, test_f_type_restricted_forbid_root); suite_add_tcase (s, tc_check_seltree); return s; } aide-0.19.3/tests/check_aide.h0000644000175000017500000000177014774422002017311 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2019,2024 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include Suite *make_attributes_suite(void); Suite *make_base64_suite(void); Suite *make_progress_suite(void); Suite *make_seltree_suite(void); Suite *make_hashsum_suite(void); aide-0.19.3/ylwrap0000755000175000017500000001546415137355012015210 0ustar00hvhaugwitzhvhaugwitz#! /bin/sh # ylwrap - wrapper for lex/yacc invocations. scriptversion=2025-06-18.21; # UTC # Copyright (C) 1996-2025 Free Software Foundation, Inc. # # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . get_dirname () { case $1 in */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';; # Otherwise, we want the empty string (not "."). esac } # guard FILE # ---------- # The CPP macro used to guard inclusion of FILE. guard () { printf '%s\n' "$1" \ | sed \ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g' \ -e 's/__*/_/g' } # quote_for_sed [STRING] # ---------------------- # Return STRING (or stdin) quoted to be used as a sed pattern. quote_for_sed () { case $# in 0) cat;; 1) printf '%s\n' "$1";; esac \ | sed -e 's|[][\\.*]|\\&|g' } case "$1" in '') echo "$0: No files given. Try '$0 --help' for more information." 1>&2 exit 1 ;; -h|--h*) cat <<\EOF Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... Wrapper for lex/yacc invocations, renaming files as desired. INPUT is the input file OUTPUT is one file PROG generates DESIRED is the file we actually want instead of OUTPUT PROGRAM is program to run ARGS are passed to PROG Any number of OUTPUT,DESIRED pairs may be used. Report bugs to . GNU Automake home page: . General help using GNU software: . EOF exit $? ;; -v|--v*) echo "ylwrap (GNU Automake) $scriptversion" exit $? ;; esac # The input. input=$1 shift # We'll later need for a correct munging of "#line" directives. input_sub_rx=`get_dirname "$input" | quote_for_sed` case $input in [\\/]* | ?:[\\/]*) # Absolute path; do nothing. ;; *) # Relative path. Make it absolute. input=`pwd`/$input ;; esac input_rx=`get_dirname "$input" | quote_for_sed` # Since DOS filename conventions don't allow two dots, # the DOS version of Bison writes out y_tab.c instead of y.tab.c # and y_tab.h instead of y.tab.h. Test to see if this is the case. y_tab_nodot=false if test -f y_tab.c || test -f y_tab.h; then y_tab_nodot=true fi # The parser itself, the first file, is the destination of the .y.c # rule in the Makefile. parser=$1 # A sed program to s/FROM/TO/g for all the FROM/TO so that, for # instance, we rename #include "y.tab.h" into #include "parse.h" # during the conversion from y.tab.c to parse.c. sed_fix_filenames= # Also rename header guards, as Bison 2.7 for instance uses its header # guard in its implementation file. sed_fix_header_guards= while test $# -ne 0; do if test x"$1" = x"--"; then shift break fi from=$1 # Handle y_tab.c and y_tab.h output by DOS if $y_tab_nodot; then case $from in "y.tab.c") from=y_tab.c;; "y.tab.h") from=y_tab.h;; esac fi shift to=$1 shift sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;" sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;" done # The program to run. prog=$1 shift # Make any relative path in $prog absolute. case $prog in [\\/]* | ?:[\\/]*) ;; *[\\/]*) prog=`pwd`/$prog ;; esac dirname=ylwrap$$ do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 mkdir $dirname || exit 1 cd $dirname case $# in 0) "$prog" "$input" ;; *) "$prog" "$@" "$input" ;; esac ret=$? if test $ret -eq 0; then for from in * do to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"` if test -f "$from"; then # If $2 is an absolute path name, then just use that, # otherwise prepend '../'. case $to in [\\/]* | ?:[\\/]*) target=$to;; *) target=../$to;; esac # Do not overwrite unchanged header files to avoid useless # recompilations. Always update the parser itself: it is the # destination of the .y.c rule in the Makefile. Divert the # output of all other files to a temporary file so we can # compare them to existing versions. if test $from != $parser; then realtarget=$target target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'` fi # Munge "#line" or "#" directives. Don't let the resulting # debug information point at an absolute srcdir. Use the real # output file name, not yy.lex.c for instance. Adjust the # include guards too. sed -e "/^#/!b" \ -e "s|$input_rx|$input_sub_rx|" \ -e "$sed_fix_filenames" \ -e "$sed_fix_header_guards" \ "$from" >"$target" || ret=$? # Check whether files must be updated. if test "$from" != "$parser"; then if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then echo "$to is unchanged" rm -f "$target" else echo "updating $to" mv -f "$target" "$realtarget" fi fi else # A missing file is only an error for the parser. This is a # blatant hack to let us support using "yacc -d". If -d is not # specified, don't fail when the header file is "missing". if test "$from" = "$parser"; then ret=1 fi fi done fi # Remove the directory. cd .. rm -rf $dirname exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp nil t) # time-stamp-start: "scriptversion=" # time-stamp-format: "%Y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: aide-0.19.3/configure.ac0000644000175000017500000003045314774422002016225 0ustar00hvhaugwitzhvhaugwitzAC_PREREQ([2.69]) m4_include([version.m4]) dnl Initialize autoconf/automake AC_INIT([aide],[AIDE_VERSION]) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE([1.10 -Wall -Werror silent-rules subdir-objects serial-tests]) AC_DEFINE_UNQUOTED(AIDEVERSION, "AIDE_VERSION") AH_TEMPLATE([AIDEVERSION], [package version]) dnl The name of the configure h-file. AC_CONFIG_HEADERS(include/config.h) dnl Checks for programs. AC_PROG_CC if test "x$ac_cv_prog_cc_c99" = xno; then AC_MSG_ERROR([AIDE needs a C99 compatible compiler]) fi AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_YACC if test "x${YACC}" != "xbison -y"; then echo "AIDE requires GNU bison" exit 5 fi AC_PROG_LEX(noyywrap) if test "x${LEX}" != "xflex"; then echo "AIDE requires GNU flex" exit 5 fi AC_CHECK_PROGS(LD, ld) AC_PATH_TOOL([PKG_CONFIG], [pkg-config], [no]) AM_PROG_CC_C_O AC_SYS_LARGEFILE dnl AC_ARG_PROGRAM AC_ARG_WITH(extra-includes, AS_HELP_STRING([--with-extra-includes],[Specify additional paths with -I to find headerfiles]), [CPPFLAGS="$CPPFLAGS $withval"] ) AC_ARG_WITH(extra-libs, AS_HELP_STRING([--with-extra-libs],[Specify additional paths with -L to find libraries]), [LDFLAGS="$LDFLAGS $withval"] ) AC_ARG_WITH(extra-link-libs, AS_HELP_STRING([--with-extra-link-libs],[Specify additional libraries to link]), [LIBS="$LIBS $withval"] ) dnl Do the right thing for glibc... AIDE_DEFS="-D_GNU_SOURCE" dnl This is borrowed from libtool if test $ac_cv_c_compiler_gnu = yes; then LD_STATIC_FLAG='-static' case "$host_os" in beos* | irix5* | irix6* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; aix*) # Below there is a dirty hack to force normal static linking with -ldl # The problem is because libdl dynamically linked with both libc and # libC (AIX C++ library), which obviously doesn't included in libraries # list by gcc. This cause undefined symbols with -static flags. # This hack allows C programs to be linked with "-static -ldl", but # we not sure about C++ programs. LD_STATIC_FLAG="$LD_STATIC_FLAG ${wl}-lC" ;; cygwin* | mingw* | os2*) # We can build DLLs from non-PIC. ;; amigaos*) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. ## pic_flag='-m68020 -resident32 -malways-restore-a4' ;; sysv4*MP*) ## if test -d /usr/nec; then ## pic_flag=-Kconform_pic ## fi ;; *) ## pic_flag='-fPIC' ;; esac else # PORTME Check for PIC flags for the system compiler. case "$host_os" in aix3* | aix4*) # All AIX code is PIC. LD_STATIC_FLAG='-bnso -bI:/lib/syscalls.exp' ;; hpux9* | hpux10* | hpux11*) # Is there a better LD_STATIC_FLAG that works with the bundled CC? ## wl='-Wl,' LD_STATIC_FLAG="${wl}-a ${wl}archive" ## pic_flag='+Z' ;; irix5* | irix6*) ## wl='-Wl,' LD_STATIC_FLAG='-non_shared' # PIC (with -KPIC) is the default. ;; cygwin* | mingw* | os2*) # We can build DLLs from non-PIC. ;; osf3* | osf4* | osf5*) # All OSF/1 code is PIC. ## wl='-Wl,' LD_STATIC_FLAG='-non_shared' ;; sco3.2v5*) ## pic_flag='-Kpic' LD_STATIC_FLAG='-dn' ## special_shlib_compile_flags='-belf' ;; solaris*) ## pic_flag='-KPIC' LD_STATIC_FLAG='-Bstatic' ## wl='-Wl,' ;; sunos4*) ## pic_flag='-PIC' LD_STATIC_FLAG='-Bstatic' ## wl='-Qoption ld ' ;; sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) ## pic_flag='-KPIC' LD_STATIC_FLAG='-Bstatic' ## wl='-Wl,' ;; uts4*) ## pic_flag='-pic' LD_STATIC_FLAG='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then ## pic_flag='-Kconform_pic' LD_STATIC_FLAG='-Bstatic' fi ;; *) ## can_build_shared=no ;; esac fi # Check whether static linking has explicitly been enabled AC_ARG_ENABLE(static,[ --enable-static enable static linking (might increase the security of aide, see README for details)], [aide_static_choice=$enableval], [aide_static_choice=no]) dnl Borrowed from dbus cc_supports_flag() { AC_MSG_CHECKING(whether $CC supports "$@") Cfile=/tmp/foo${$} touch ${Cfile}.c $CC -c "$@" ${Cfile}.c -o ${Cfile}.o >/dev/null 2>&1 rc=$? rm -f ${Cfile}.c ${Cfile}.o case $rc in 0) AC_MSG_RESULT(yes);; *) AC_MSG_RESULT(no);; esac return $rc } dnl Borrowed from dbus ld_supports_flag() { AC_MSG_CHECKING([whether $LD supports "$@"]) AC_LINK_IFELSE([AC_LANG_PROGRAM([ int one(void) { return 1; } int two(void) { return 2; } ], [ two(); ] ) ] , [_ac_ld_flag_supported=yes], [_ac_ld_flag_supported=no]) if test "$_ac_ld_flag_supported" = "yes"; then rm -f conftest.c touch conftest.c if $CC -c conftest.c; then ld_out=`$LD $@ -o conftest conftest.o 2>&1` ld_ret=$? if test $ld_ret -ne 0 ; then _ac_ld_flag_supported=no elif echo "$ld_out" | egrep 'option ignored|^usage:|unrecognized option|illegal option' >/dev/null ; then _ac_ld_flag_supported=no fi fi rm -f conftest.c conftest.o conftest fi AC_MSG_RESULT($_ac_ld_flag_supported) if test "$_ac_ld_flag_supported" = "yes" ; then return 0 else return 1 fi } if test "$aide_static_choice" != "yes"; then LD_STATIC_FLAG="" EXTRA_LDFLAGS="" EXTRA_CFLAGS="" if test x$CC = "xgcc"; then if ld_supports_flag -z,relro; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-z,relro" fi if ld_supports_flag -z,now; then EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-z,now" fi if cc_supports_flag -fPIE -DPIE; then EXTRA_CFLAGS="$EXTRA_CFLAGS -fPIE -DPIE" EXTRA_LDFLAGS="$EXTRA_LDFLAGS -pie" fi dnl Check for some optional warnings if cc_supports_flag -Wundef; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wundef" fi if cc_supports_flag -Wmissing-format-attribute; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wmissing-format-attribute" fi if cc_supports_flag -Wshadow; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wshadow" fi if cc_supports_flag -Wlogical-op; then EXTRA_CFLAGS="$EXTRA_CFLAGS -Wlogical-op" fi fi fi dnl This macro is new in autoconf-2.13 AC_SEARCH_LIBS(syslog, bsd socket inet, [AC_DEFINE(HAVE_SYSLOG,1,[syslog available?])]) AC_CHECK_FUNCS(vsyslog) AC_C_BIGENDIAN([AC_DEFINE(BIG_ENDIAN_HOST,1,[big endian])], [AC_DEFINE(LITTLE_ENDIAN_HOST,1,[little endian])]) AC_CHECK_TYPES([byte, ushort, ulong, u16, u32, u64]) AC_CHECK_SIZEOF(unsigned short, 2) AC_CHECK_SIZEOF(unsigned int, 4) AC_CHECK_SIZEOF(unsigned long, 4) AC_CHECK_SIZEOF(unsigned long long, 8) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(uid_t) AC_CHECK_SIZEOF(gid_t) AC_CHECK_SIZEOF(ino_t) AC_CHECK_SIZEOF(nlink_t) AC_CHECK_SIZEOF(off_t) AC_CHECK_SIZEOF(blkcnt_t) AC_CHECK_FUNCS(strtoll strtoimax readdir) AC_CHECK_FUNCS(stricmp strnstr strnlen) AC_CHECK_FUNCS(fcntl ftruncate posix_fadvise asprintf snprintf \ vasprintf vsnprintf va_copy __va_copy) AC_CHECK_FUNCS(sigabbrev_np) AC_CHECK_HEADERS(sys/prctl.h) AC_CHECK_HEADERS(syslog.h inttypes.h fcntl.h ctype.h) AIDE_PKG_CHECK_MANDATORY(pcre2, PCRE2, libpcre2-8) AX_PTHREAD(compoptionstring="${compoptionstring}use pthread: mandatory\\n", [AC_MSG_ERROR([AIDE requires pthread])]) AC_ARG_WITH([fstype], AS_HELP_STRING([--without-fstype], [Disable file system type support for restricted rules (Linux only)]), [with_fstype=$withval], [with_fstype=yes] ) AC_MSG_CHECKING(for fstype support (Linux only)) case "${target_os}" in linux*) if test "x$with_fstype" != xno; then AC_DEFINE(HAVE_FSTYPE,1,[file system type support?]) fi AC_MSG_RESULT($with_fstype); ;; *) AC_MSG_RESULT(no); ;; esac AIDE_PKG_CHECK(zlib, zlib compression, yes, ZLIB, zlib) AIDE_PKG_CHECK([posix-acl], POSIX ACLs, no, POSIX_ACL, libacl, acl) if test "x$with_libacl" = xyes; then AC_DEFINE(WITH_ACL, 1, [use ACL]) fi AIDE_PKG_CHECK(selinux, SELinux, no, SELINUX, libselinux, selinux, >= 3.4) AIDE_PKG_CHECK(xattr, xattr, no, XATTR, libattr, xattrs) AIDE_PKG_CHECK(capabilities, POSIX 1003.1e capabilities, no, CAPABILITIES, libcap, caps) AIDE_PKG_CHECK(e2fsattrs, e2fsattrs, no, E2FSATTRS, e2p, e2fsattrs) AIDE_PKG_CHECK(curl, cURL, no, CURL, libcurl) AC_MSG_CHECKING(for Nettle) AC_ARG_WITH([nettle], AS_HELP_STRING([--with-nettle], [use Nettle crypto library (default: check)]), [with_nettle=$withval], [with_nettle=check]) AC_MSG_RESULT([$with_nettle]) AC_MSG_CHECKING(for GNU crypto library) AC_ARG_WITH([gcrypt], AS_HELP_STRING([--with-gcrypt], [use GNU crypto library (default: check)]), [with_gcrypt=$withval], [with_gcrypt=check]) AC_MSG_RESULT([$with_gcrypt]) AIDE_PKG_CHECK_MODULES_OPTIONAL(nettle, NETTLE, nettle, >= 3.7) AS_IF([test x"$with_nettle" = xyes], [ AS_IF([test x"$with_gcrypt" = xcheck], [ with_gcrypt=no ]) ] ) AIDE_PKG_CHECK_MODULES_OPTIONAL(gcrypt, GCRYPT, libgcrypt) AS_IF([test x"$with_nettle" != xno && test x"$with_gcrypt" != xno], [ AC_MSG_ERROR([Using gcrypt together with Nettle makes no sense. To disable nettle use --without-nettle]) ]) AS_IF([test x"$with_nettle" = xno && test x"$with_gcrypt" = xno], [ AC_MSG_ERROR([AIDE requires nettle or libcrypt for hashsum calculation]) ]) compoptionstring="${compoptionstring}use Nettle crypto library: $with_nettle\\n" AM_CONDITIONAL(HAVE_NETTLE, [test "x$NETTLE_LIBS" != "x"]) compoptionstring="${compoptionstring}use GNU crypto library: $with_gcrypt\\n" AM_CONDITIONAL(HAVE_GCRYPT, [test "x$GCRYPT_LIBS" != "x"]) AIDE_PKG_CHECK(audit, Linux Auditing Framework, no, AUDIT, audit) AIDE_PKG_CHECK_HEADERS(locale, locale, no, LOCALE, [libintl.h]) if test "x$with_locale" = xyes; then AC_DEFINE_UNQUOTED(LOCALEDIR,"$prefix/lib/locale",[Localedir to use]) fi AIDE_COMPILE_TIME_OPTION(syslog_ident, syslog-ident, syslog ident, "aide") AC_DEFINE_UNQUOTED(AIDE_IDENT, "$with_syslog_ident", [syslog ident]) AIDE_COMPILE_TIME_OPTION(syslog_logopt, syslog-logopt, syslog logopt, LOG_CONS) AC_DEFINE_UNQUOTED(AIDE_LOGOPT, $with_syslog_logopt, [syslog logopt]) AIDE_COMPILE_TIME_OPTION(syslog_priority, syslog-priority, syslog priority, LOG_NOTICE) AC_DEFINE_UNQUOTED(AIDE_SYSLOG_PRIORITY, $with_syslog_priority, [syslog priority]) AIDE_COMPILE_TIME_OPTION(syslog_facility, syslog-facility, default syslog facility, LOG_LOCAL0) AC_DEFINE_UNQUOTED(AIDE_SYSLOG_FACILITY, $with_syslog_facility, [syslog facility]) PKG_CHECK_MODULES(CHECK, [check >= 0.9.4], , [AC_MSG_RESULT([Check not found (testing via 'make check' disabled)])]) AM_CONDITIONAL(HAVE_CHECK, [test "x$CHECK_LIBS" != "x"]) AC_ARG_WITH([config_file], AS_HELP_STRING([--with-config-file=config-file],[specify default config file (use --without-config-file to disable default config file)]), [with_config_file=$withval],[with_config_file=yes]) if test "$with_config_file" != "no"; then if test "$with_config_file" != "yes"; then config_file=$with_config_file else if test "x$sysconfdir" != x'${prefix}/etc'; then config_file=`eval echo "$sysconfdir/aide.conf"` elif test "x$prefix" != xNONE; then config_file="$prefix/etc/aide.conf" else config_file="$ac_default_prefix/etc/aide.conf" fi fi AC_DEFINE_UNQUOTED(CONFIG_FILE,"$config_file",[Location of configuration file]) fi AC_ARG_ENABLE([default_db], AS_HELP_STRING([--disable-default-db],[do not set default values for database_in and database_out config options]), [enable_default_db=$enableval],[enable_default_db=yes]) if test "$enable_default_db" = "yes"; then if test "x$sysconfdir" != x'${prefix}/etc'; then evalled_sysconfdir=`eval echo "$sysconfdir"` default_db="$evalled_sysconfdir/aide.db" default_db_out="$evalled_sysconfdir/aide.db.new" elif test "x$prefix" != xNONE; then default_db="$prefix/etc/aide.db" default_db_out="$prefix/etc/aide.db.new" else default_db="$ac_default_prefix/etc/aide.db" default_db_out="$ac_default_prefix/etc/aide.db.new" fi AC_DEFINE_UNQUOTED(DEFAULT_DB,"file:$default_db",[Default location of signature database]) AC_DEFINE_UNQUOTED(DEFAULT_DB_OUT,"file:$default_db_out",[Default output location for newly-generated signature database]) fi extrasub="s&@AIDEVERSION@&$PACKAGE_VERSION&;t t" AC_DEFINE_UNQUOTED(AIDECOMPILEOPTIONS, "${compoptionstring}",[Compile-time options displayed in -v output]) dnl Add in the optional compiler features LDFLAGS="$LDFLAGS $LD_STATIC_FLAG $EXTRA_LDFLAGS" CFLAGS="$CFLAGS $EXTRA_CFLAGS" AC_SUBST(AIDE_DEFS) AC_CONFIG_FILES([Makefile]) AC_OUTPUT aide-0.19.3/doc/0000755000175000017500000000000015137355021014477 5ustar00hvhaugwitzhvhaugwitzaide-0.19.3/doc/aide.conf.50000644000175000017500000010715115137354776016440 0ustar00hvhaugwitzhvhaugwitz.TH AIDE.CONF 5 "2026-01-31" "aide v0.19.3" "AIDE" .SH NAME aide.conf - The configuration file for Advanced Intrusion Detection Environment .PP .SH SYNOPSIS \fBaide.conf\fP is the configuration file for Advanced Intrusion Detection Environment. \fBaide.conf\fP contains the runtime configuration aide uses to initialize or check the AIDE database. .PP .SH "FILE FORMAT" aide.conf is case-sensitive. Leading and trailing white spaces are ignored. Each config line must end with new line. .PP AIDE uses the backslash character (\fB\e\fR) as escape character for ' ' (space), '@' and '\e' (backslash) (e.g. '\e ' or '\e@'). To literally match a '\fB\e\fR' in a file path with a regular expression you have to escape the backslash twice (i.e. '\fB\e\e\e\e\fR'). .PP There are three types of lines in \fBaide.conf\fP. First there are the configuration options which are used to set configuration parameters and define groups. Second, there are (restricted) rules that are used to indicate which files/directories from the file system are added to the database. Third, macro lines define or undefine variables within the config file. Lines beginning with # are ignored as comments. .PP .SH "CONFIG OPTIONS" .PP These lines have the format parameter=value. See URLS for a list of valid urls. .PP .TP database_in (type: URL, default: see \fB--version\fP output, added in AIDE v0.17) .TQ database (REMOVED in AIDE v0.19) The url from which database is read. There can only be one of these lines. If there are multiple database lines then the first is used. .RS .B Examples: .RS 3 .nf .B database_in=file:/var/lib/aide/aide.db .fi .RS 3 Read database locally from \fI/var/lib/aide/aide.db\fR. .RE .RE .RS 3 .nf .B database_in=stdin .fi .RS 3 Read database from \fIstdin\fR. .RE .RE .RS 3 .nf .B database_in=https://example.com/aide.db .fi .RS 3 Read database remotely from \fIhttps://example.com/aide.db\fR. .RE .RE .RE .IP "database_out (type: URL, default: see \fB--version\fP output)" The url to which the new database is written to. There can only be one of these lines. If there are multiple database_out lines then the first is used. .IP "database_new (type: URL, default: \fB\fP)" The url from which the other database for \-\-compare is read. .IP "database_attrs (type: attribute expression, default: \fBH\fP, added in AIDE v0.16)" The attributes of the (uncompressed) database files which are to be added to the reports in report level >= \fBdatabase_attributes\fP . Only checksum attributes are supported. To disable set .I database_attrs to .RB ' E '. .IP "database_add_metadata (type: bool, default: \fBtrue\fR, added in AIDE v0.16)" Whether to add the AIDE version and the time of database generation as comments to the database file or not. This option may be set to false by default in a future release. .IP "log_level (type: log level, default: \fBwarning\fR, added in AIDE v0.17)" The log level to use. Log messages are written to \fIstderr\fR. If there are multiple \fIlog_level\fR lines then the first one is used. The \-\-log-level or \-L command line option overwrites this option. .RS The following log levels are available: .RS \fBerror\fP: show unrecoverable issues that have to be handled by the user. Errors are fatal to the AIDE process. \fBwarning\fP: additionally show recoverable issues that most likely lead to unexpected behaviour and should be handled by the user \fBnotice\fP: additionally show recoverable issues that sometimes lead to unexpected behaviour and might be handled by the user. \fBinfo\fP: additionally show informational messages \fBcompare\fP: additionally show messages to help to debug file comparison and (special) attribute handling The log levels below are very verbose and can easily generate multiple gigabytes of log data (depending on the number of processed files and the size of the rule tree). For debugging it is recommended to use these log levels together with the \fI--limit\fR parameter (see aide (1) for details). \fBrule\fP: additionally show messages to help to debug the path rule matching \fBconfig\fP: additionally show messages to help to debug config and rule parsing \fBdebug\fP: additionally show messages that are useful to debug the application \fBlimit\fP: additionally show messages about skipped entries due to limit match \fBthread\fP: additionally show messages about thread processing (e.g. broadcast events) \fBtrace\fP: additionally show messages about the internal data structures and the flow of the application (e.g. in-loop logging) (extremely verbose) .RE .RE .IP "verbose (type: number, range: 0 - 255, default: \fB5\fR, REMOVED in AIDE v0.17)" Removed, use \fBlog_level\fR and \fBreport_level\fR options instead. .IP "gzip_dbout (type: bool, default: \fBfalse\fR)" Whether the output to the database is gzipped or not. This option is available only if zlib support is compiled in. .IP "root_prefix (type: path, default: \fB\fR, added in AIDE v0.16)" The prefix to strip from each file name in the file system before applying the rules and writing to database. AIDE removes a trailing slash from the prefix. If there are multiple root_prefix lines then the first one is used. This option has no effect in compare mode. .IP "acl_no_symlink_follow (type: bool, default: \fBfalse\fR)" Whether to check ACLs for symlinks or not. This option is available only if acl support is compiled in. .IP "warn_dead_symlinks (type: path, default: \fBfalse\fR)" Whether to warn about dead symlinks or not. .IP "config_version (type: string, default: \fB\fR)" The value of config_version is printed in the report and also printed to the database. This is for informational purposes only. It has no other functionality. .IP "config_check_warn_unrestricted_rules (type: bool, default: \fBfalse\fR, added in AIDE v0.18)" Whether to warn on unrestricted rules during config check. To explicitly define unrestricted rules use \fB0\fR (zero) as restriction character. .IP "num_workers (type: number|percentage, default: \fB1\fR, added in AIDE v0.18)" Specifies the number of simultaneous workers (threads) for file attribute processing (i.a. hashsum calculation). The number of workers can be a positive integer (e.g. '4') or the percentage of the available processors (e.g. '60%'). The resulting number of workers is rounded up to the next integer (e.g. '60%' of 8 processors results in 5 workers). If there are multiple \fInum_workers\fR lines then the first one is used. Use 0 (zero) to disable (multi-threaded) workers. The default value 1 (single worker thread) may be changed in a future release. .PP .SH REPORT OPTIONS .PP .IP "report_url (type: URL, default: \fBstdout\fR)" The URL that the output is written to. Multiple instances of the \fBreport_url\fR option are supported. .RS .B Examples: .RS 3 .nf .B report_url=file:/var/log/aide.log .fi .RS 3 Write report to \fI/var/log/aide.log\fR. .RE .RE .RS 3 .nf .B report_url=stdout .fi .RS 3 Write report to \fIstdout\fR. .RE .RE .RS 3 .nf .B report_url=syslog: .fi .RS 3 Write report to \fIsyslog\fR using \fILOG_FACILITY\fR. .RE .RE .RE .PP The following report options are available (to take effect they have to be set before \fBreport_url\fR): .PP .IP "report_level (type: report level, default: \fBchanged_attributes\fR, added in AIDE v0.17)" The report level to use. The available report levels are as follows: .RS \fBminimal\fP: print single line whether AIDE found differences to the database \fBsummary\fP: additionally print number of added, removed and changed files \fBdatabase_attributes\fP: additionally print database checksums \fBlist_entries\fP: additionally print lists of added, removed and changed entries \fBchanged_attributes\fP: additionally print details about changed entries .RS .B Example: .RS 3 .EX File: /var/lib/apt/extended_states Perm : -rw-r--r-- | -rw------- Uid : 0 | 106 .EE .RE The left column shows the old value (e.g. from the \fIdatabase_in\fR database) and the right column shows the new value (e.g. from the file system). .RE \fBadded_removed_attributes\fP: additionally print details about added and removed attributes \fBadded_removed_entries\fP: additionally print details about added and removed entries .RE .IP "report_format (type: report format, default: \fBplain\fR, added in AIDE v0.18)" The report format to use. The available report formats are as follows: .RS \fBplain\fP: Print report in plain human-readable format. \fBjson\fP: Print report in json machine-readable format. .RE .IP "report_base16 (type: bool, default: \fBfalse\fR, added in AIDE v0.17)" Base16 encode the checksums in the report. The default is to report checksums in base64 encoding. .IP "report_detailed_init (type: bool, default: \fBfalse\fR, added in AIDE v0.16)" Report added files (report level >= \fBlist_entries\fP) and their details (report level >= \fBadded_removed_entries\fP) in initialization mode. .IP "report_quiet (type: bool, default: \fBfalse\fR, added in AIDE v0.16)" Suppress report output if no differences to the database have been found. .IP "report_append (type: bool, default: \fBfalse\fR, added in AIDE v0.17)" Append to the report URL. .TP report_grouped (type: bool, default: \fBtrue\fR, added in AIDE v0.17) .TQ grouped (REMOVED in AIDE v0.19) Group the files in the report by added, removed and changed files. .TP report_summarize_changes (type: bool, default: \fBtrue\fR, added in AIDE v0.17) .TQ summarize_changes (REMOVED in AIDE v0.19) Summarize changes in the added, removed and changed files sections of the report. The general format is like the string YlZbpugamcinHAXSECF, where Y is replaced by the file-type ('\fBf\fP' for a regular file, '\fBd\fP' for a directory, '\fBl\fP' for a symbolic link, '\fBc\fP' for a character device, '\fBb\fP' for a block device, '\fBp\fP' for a FIFO, '\fBs\fP' for a unix socket, '\fBD\fP' for a Solaris door, '\fBP\fP' for a Solaris event port, '\fB!\fP' if file type has changed and '\fB?\fP' otherwise). The Z is replaced as follows: A '\fB=\fP' means that the size has not changed, a '\fB<\fP' reports a shrinked size and a '\fB>\fP' reports a grown size. The other letters in the string are the actual letters that will be output if the associated attribute for the item has been changed or a '\fB.\fP' for no change. Otherwise a '\fB+\fP' is shown if the attribute has been added, a '\fB-\fP' if it has been removed, a '\fB:\fP' if the attribute is ignored (but not forced) or a ' ' if the attribute has not been checked. The exceptions to this are: (1) a newly created file replaces each letter with a '\fB+\fP', and (2) a removed file replaces each letter with a '\fB-\fP'. The attribute that is associated with each letter is as follows: .RS .IP o An \fBl\fP means that the link name has changed. .IP o A \fBb\fP means that the block count has changed. .IP o A \fBp\fP means that the permissions have changed. .IP o A \fBu\fP means that the uid has changed. .IP o A \fBg\fP means that the gid has changed. .IP o An \fBa\fP means that the access time has changed. .IP o An \fBm\fP means that the modification time has changed. .IP o A \fBc\fP means that the change time has changed. .IP o An \fBi\fP means that the inode has changed. .IP o An \fBn\fP means that the link count has changed. .IP o An \fBH\fP means that one or more message digests have changed. .IP o An \fBF\fP means that one file system type has changed (Linux only). .RE .RS The following letters are only available when explicitly enabled using configure: .RE .RS .IP o An \fBA\fP means that the access control list has changed. .IP o An \fBX\fP means that the extended attributes have changed. .IP o An \fBS\fP means that the SELinux attributes have changed. .IP o An \fBE\fP means that the file attributes on a second extended file system have changed. .IP o A \fBC\fP means that the file capabilities have changed. .RE .IP "report_ignore_added_attrs (type: attribute expression, default: \fBempty\fR, added in AIDE v0.16)" Attributes whose addition is to be ignored in the report. .IP "report_ignore_removed_attrs (type: attribute expression, default: \fBempty\fR, added in AIDE v0.16)" Attributes whose removal is to be ignored in the report. .TP report_ignore_changed_attrs (type: attribute expression, default: \fBempty\fR, added in AIDE v0.16) .TQ ignore_list (REMOVED in AIDE v0.17) Attributes whose change is to be ignored in the report. .TP report_force_attrs (type: attribute expression, default: \fBempty\fR, added in AIDE v0.16) .TQ report_attributes (REMOVED in AIDE v0.17) Attributes which are always printed in the report for changed files. If an attribute is both ignored and forced the attribute is not considered for file change but printed in the final report as long as the file has been otherwise changed. .IP "report_ignore_e2fsattrs (type: string, default: \fB0\fR, added in AIDE v0.16)" List (no delimiter) of ext2 file attributes which are to be ignored in the report. See .BR chattr (1) for the available attributes. Use \fB0\fR (zero) to not ignore any attribute. Ignored attributes are represented by a ':' in the report. By default AIDE also reports changes of the read-only attributes mentioned in .BR chattr (1) (see example below how to ignore those changes). .RS .B Example: .RS 3 Ignore changes of the read-only ext2 file attributes verify (V), inline data (N), indexed directory (I) and encrypted (E): .RS 3 .nf report_ignore_e2fsattrs=VNIE .fi .RE .RE .RE .PP .SH "GROUPS" .PP Groups are aggregations of attributes. Group definitions have the format = . Group names are limited to alphanumeric characters (\fBA-Za-z0-9\fP). See ATTRIBUTES for a description of all available attributes. .RE .B Default groups .TP .B "R" p+ftype+i+l+n+u+g+s+m+c+sha3_256+X .TP .B "L" p+ftype+i+l+n+u+g+X .TP .B ">" Growing file p+ftype+l+u+g+i+n+s+growing+X .TP .B "H" all compiled in (and not deprecated) hashsums (added in AIDE v0.17) .TP .B "X" acl+selinux+xattrs+e2fsattrs+caps (if attributes are compiled in, added in AIDE v0.16) .TP .B "E" Empty group .TP Use 'aide --version' to list the default compound groups. .RE .PP .SH "RULES" .PP AIDE supports three types of rules: .TP .B "Regular rule:" Files and directories matching the regular expression are added to the database. .TP .B "Recursive negative rule:" ! Files and directories matching the regular expression are excluded and NOT added to the database. The children of directories and sub-directories are recursed into and only not added to the database if they also match the regular expression. .TP .B "Non-recursive negative rule (added in AIDE v0.19)" - Files and directories matching the regular expression are excluded and NOT added the database. The children of directories and sub-directories are not recursed into and hence not added to the database by any means. .TP .B "Equals rule:" = Files and directories matching the regular expression are added to the database. The children of directories are only added if the regular expression ends with a "/". The children of sub-directories are not added to the database. .PP Every regular expression has to start with an explicit "/". An implicit ^ is added in front of each regular expression. In other words, the regular expressions are matched at the first position against the complete path. Special characters can be escaped using two-digit URL encoding (for example, %20 to represent a space). AIDE uses a deepest-match algorithm to find the tree node to search, but a first-match algorithm inside the node. (see also \fBrule\fP log level). See EXAMPLES for examples. .PP More in-depth discussion of the selection algorithm can be found in the AIDE manual. .IP .PP .SH "RESTRICTED RULES" Restricted rules are like normal rules but can be restricted to file types (added in AIDE v0.16) and/or file system types (added in AIDE v0.19, Linux only). The syntax of restricted rules is as follows: .B "Restricted regular rule" .RS 3 .nf .fi Files and directories matching both the regular expression and the restriction expression are added the database. .RE .B "Restricted recursive negative rule" .RS 3 .nf ! .fi Files and directories matching both the regular expression and the restriction expression are excluded and NOT added the database. The children of directories and sub-directories are recursed into and only excluded if they also match the regular expression as well as the restriction. .RE .B "Restricted non-recursive negative rule (added in AIDE v0.19)" .RS 3 .nf - .fi Files and directories matching both the regular expression and the restriction expression are excluded and NOT added the database. The children of directories and sub-directories are not recursed into and hence not added to the database by any means. .RE .B "Restricted equals rule" .RS 3 .nf = .fi Files and directories matching both the regular expression and the restriction expression are added the database. The children of directories are only added if the regular expression ends with a "/". The children of sub-directories are not added to the database. .RE .B Restriction expression .RS 3 An restriction expression is of the following form: .nf : | = | = .fi .RE .B File types .RS 3 The following file types are supported: .RS 3 .TP .B "\fBf\fP" restrict rule to regular files .TP .B "\fBd\fP" restrict rule to directories .TP .B "\fBl\fP" restrict rule to symbolic links .TP .B "\fBc\fP" restrict rule to character devices .TP .B "\fBb\fP" restrict rule to block devices .TP .B "\fBp\fP" restrict rule to FIFO files .TP .B "\fBs\fP" restrict rule to UNIX sockets .TP .B "\fBD\fP" restrict rule to Solaris doors .TP .B "\fBP\fP" restrict rule to Solaris event ports .RE .PP Multiple file type restrictions can be given as a comma-separated list. .RE .B "File system types (Linux only)" .RS 3 The file system type restriction can be specified by file system types magic number (e.g. '0x01021994' for tmpfs) or by its name (use 'aide --version' to list the available file system type names). The magic number must start with '0x' and be formatted in hexdecimal format. .RE .B "Empty restriction" .RS 3 To explicitly don't restrict a rule use .B "\fB0\fR" (added in AIDE v0.18). .RE .B Examples: .RS 3 .nf / d,f R .fi .RS 3 Only add directories and files to the database. .RE .RE .RS 3 .nf /boot/efi$ d=vfat R .fi .RS 3 Only add \fB/boot/efi\fR to the database if it is a directory and mounted on \fBvfat\fR. .RE .RE .RS 3 .nf !/dev =0x01021994 .fi .RS 3 Exclude \fB/dev\fR and any children that are mounted on \fBtmpfs\fR (\fBtmpfs\fR magic number: \fB0x01021994\fR). .RE .RE .RS 3 .nf -/dev =tmpfs .fi .RS 3 Exclude \fB/dev\fR and all children, if \fB/dev\fR is mounted on \fBtmpfs\fR. .RE .RE .PP .SH "MACRO LINES" .PP .IP "@@define \fBVAR\fR \fBval\fR" Define variable \fBVAR\fR to value \fBval\fR. .IP "@@undef \fBVAR\fR" Undefine variable \fBVAR\fR. .TP @@if \fBboolean_expression\fR (added in AIDE v0.18) .TQ @@else .TQ @@endif @@if begins an if statement. It must be terminated with an @@endif statement. The lines between @@if and @@endif are used if the \fBboolean_expression\fR evaluates to \fBtrue\fR. If there is an @@else statement then the part between @@if and @@else is used if \fBboolean_expression\fR evaluates to \fBtrue\fR otherwise the part between @@else and @@endif is used. .RS Available operators and functions in boolean expressions: .RS 3 .nf .B not \fIboolean_expression\fR .fi .RS 3 Evaluates to true if the \fIboolean_expression\fR is false, and false if the \fIboolean_expression\fR is true. .RE .RE .RS 3 .nf .B defined \fIVARIABLE\fR .fi .RS 3 Evaluates to \fBtrue\fR if \fIVARIABLE\fR is defined. .RE .RE .RS 3 .nf .B hostname \fIHOSTNAME\fR .fi .RS 3 Evaluates to \fBtrue\fR if \fIHOSTNAME\fR equals the \fBhostname\fR of the machine that AIDE is running on. \fBhostname\fR is the name of the host without the domainname (ie 'hostname', not 'hostname.example.com'). .RE .RE .RS 3 .nf .B exists \fIPATH\fR .fi .RS 3 Evaluates to \fBtrue\fR if \fIPATH\fR exists. .RE .RE .RS 3 .nf .B \fIVERSION_STRING1\fR \fBversion_ge\fR \fIVERSION_STRING2\fR (added in AIDE v0.19) .fi .RS 3 Evaluates to \fBtrue\fR if \fIVERSION_STRING1\fR is greater than or equal to \fIVERSION_STRING2\fR (e.g. 0.19.1 \fBversion_ge\fR 0.18 evaluates to \fBtrue\fR and 2.17 \fBversion_ge\fR 1.1 to \fBfalse\fR). The version strings must be in the format MAJOR.MINOR.PATCH (minor and patch version can be omitted, any version suffix (e.g. for pre-release) will be truncated). .RE .RE .RE .IP "@@ifdef \fBVARIABLE\fR (\fBDEPRECATED\fR since AIDE v0.18, will be removed in AIDE v0.20)" same as \fB@@if defined VARIABLE\fR .IP "@@ifndef \fBVARIABLE\fR (\fBDEPRECATED\fR since AIDE v0.18, will be removed in AIDE v0.20)" same as \fB@@if not defined VARIABLE\fR .IP "@@ifhost \fBHOSTNAME\fR (\fBDEPRECATED\fR since AIDE v0.18, will be removed in AIDE v0.20)" same as \fB@@if hostname HOSTNAME\fR .IP "@@ifnhost \fBHOSTNAME\fR (\fBDEPRECATED\fR since AIDE v0.18, will be removed in AIDE v0.20)" same as \fB@@if not hostname HOSTNAME\fR .IP "@@{\fBVAR\fR}" @@{\fBVAR\fR} is replaced with the value of the variable \fBVAR\fR. If variable \fBVAR\fR is not defined an empty string is used. Variables are supported in strings and in regular expressions of rules. .RS Pre-defined marco variables: .RS 3 \fB@@{AIDE_VERSION}\fP: the version of AIDE .RE .RS 3 \fB@@{HOSTNAME}\fP: the hostname of the current system .RE .RE .IP "@@include \fBFILE\fR" Include \fBFILE\fR. The content of the file is used as if it were inserted in this part of the config file. The maximum depth of nested includes is 16. .IP "@@include \fBDIRECTORY\fR \fBREGEX\fR [\fBRULE_PREFIX\fR] (added in AIDE v0.17)" Include all (regular) files found in \fBDIRECTORY\fR matching regular expression \fBREGEX\fR (sub-directories are ignored). The files are included in lexical sort order. If \fBRULE_PREFIX\fR (added in AIDE v0.18) is set, all rules included by the statement are prefixed with given \fBRULE_PREFIX\fR. Prefixes from nested include statements are concatenated. The content of the files is used as if it were inserted in this part of the config file. .TP @@x_include \fBFILE\fR (added in AIDE v0.17) .TQ @@x_include \fBDIRECTORY\fR \fBREGEX\fR [\fBRULE_PREFIX\fR] (added in AIDE v0.17) \fB@x_include\fR is identical to \fB@@include\fR, except that if a config file is executable is is run and the output is used as config. If the executable file exits with status greater than zero or writes to stderr aide stops with an error. For security reasons \fBDIRECTORY\fR and each executable config file must be owned by the current user or root. They must not be group- or world-writable. .IP "@@x_include_setenv \fBVAR\fR \fBVALUE\fR (added in AIDE v0.17)" Adds the variable \fBVAR\fR with the value \fBVALUE\fR to the environment used for config file execution. Environment variable names are limited to alphanumeric characters (\fBA-Za-z0-9\fP) and the underscore '\fB_\fR' and must not begin with a digit. .PP .SH TYPES .B bool .RS 3 Valid values are \fByes\fR, \fBtrue\fR, \fBno\fR or \fBfalse\fR. .RE .B "attribute expression" .RS 3 An attribute expression is of the following form: .IP .nf : | + | - .fi .RE .B URLS .RS 3 Urls can be one of the following. Input urls cannot be used as outputs and vice versa. .RS .IP "stdout" .IP "stderr" Output is sent to stdout, stderr respectively. .IP "stdin" Input is read from stdin. .IP "file:/\fBpath\fR" Input is read from \fBpath\fR or output is written to \fBpath\fR. .IP "fd:\fBnumber\fR" Input is read from filedescriptor \fBnumber\fR or output is written to \fBnumber\fR. .IP "syslog:\fBLOG_FACILITY\fR" Output is written to syslog using \fILOG_FACILITY\fR. .RE .RE .SH "ATTRIBUTES" .PP .B "File attributes" .TP .B "\fBftype\fR" file type (added in AIDE v0.15) .TP .B "\fBfstype\fR" file system type (Linux-only, added in AIDE v0.19) .TP .B "\fBp\fR" permissions .TP .B "\fBi\fR" inode .TP .B "\fBl\fR" link name (symbolic links only) .TP .B "\fBn\fR" number of links .TP .B "\fBu\fR" user .TP .B "\fBg\fR" group .TP .B "\fBs\fR" size .TP .B "\fBb\fR" block count .TP .B "\fBm\fR" mtime .TP .B "\fBa\fR" atime .TP .B "\fBc\fR" ctime .TP .B "\fBacl\fR" access control list (requires \fIlibacl\fR, Linux-only) .TP .B "\fBselinux\fR" selinux attributes (requires \fIlibselinux\fR, Linux-only) .TP .B "\fBxattrs\fR" extended attributes (requires \fIlibattr\fR, Linux-only) .TP .B "\fBe2fsattrs\fR" file attributes on a Linux file system, see also \fB report_ignore_e2fsattrs \fP option (requires \fIlibext2fs\fR, added in AIDE v0.15) .TP .B "\fBcaps\fR" file capabilities (regular files only) (requires \fIlibcap\fR, Linux-only, added in AIDE v0.17) .PP Use 'aide --version' to show which compiled-in attributes are available. .PP .B "Special attributes" .TP .B "\fBS\fR" check for growing size (\fBDEPRECATED\fR since AIDE v0.18, will be removed in AIDE v0.20) Use \fBgrowing+s\fR attributes instead .TP .B "\fBI\fR" ignore changed filename When \fBI\fR is used, the inode of the new file is used to search for a moved source file in the old database. Source and target file have to be located in the same directory and must share the same attributes (except for special attributes \fBANF\fR, \fBARF\fR, \fBI\fR, \fBgrowing\fR, and \fBcompressed\fR). For moved entries a change of the \fBctime\fR attribute is ignored. .TP .B "\fBgrowing\fR" ignore growing file (added in AIDE v0.18) When \fBgrowing\fR is used, changes of the following attributes are ignored: \fBsize\fR: if new size is greater than old size \fBbcount\fR: if new bcount is greater than old bcount \fBatime\fR: if new atime is greater than old atime \fBmtime\fR: if new mtime is greater than old mtime \fBctime\fR: if new ctime is greater than old ctime \fBhashsums\fR: if the hashsum of the new file restricted to the old size equals the hashsums of the old file For hashsum attributes the \fBgrowing\fR attribute is ignored in compare mode. .TP .B "\fBcompressed\fR" ignore compressed file (added in AIDE v0.18) When \fBcompressed\fR is used, the uncompressed hashsums of the new compressed file (supported compressions: \fBgzip\fR) are used to search for the uncompressed file in the old database. The old uncompressed and the new compressed file have to be located in the same directory and must share the same attributes (except for special attributes \fBANF\fR, \fBARF\fR, \fBI\fR, \fBgrowing\fR, and \fBcompressed\fR) including at least one common hashsum. Changes of the \fBinode\fR, \fBsize\fR, \fBbcount\fR and \fBctime\fR attributes are ignored. The \fBgrowing\fR attribute (i.e. the old file size) is not considered for compressed files during the calculation of the uncompressed hashsums. The \fBcompressed\fR attribute is ignored in compare mode. .TP .B "\fBANF\fR" allow new files When 'ANF' is used, new files are added to the new database, but are ignored in the report. .TP .B "\fBARF\fR" allow removed files When 'ARF' is used, files missing on disk are omitted from the new database, but are ignored in the report. .PP .B Hashsums attributes (regular files only) .RS 3 .TP .B "sha256" SHA-256 checksum .TP .B "sha512" SHA-512 checksum .TP .IP "\fBsha512_256\fR (added in AIDE v0.19)" SHA-512 checksum truncated to 256 output bits .TP .IP "\fBsha3_256\fR (added in AIDE v0.19)" SHA3-256 checksum .TP .IP "\fBsha3_512\fR (added in AIDE v0.19)" SHA3-512 checksum .TP .IP "\fBstribog256\fR (added in AIDE v0.17)" GOST R 34.11-2012, 256 bit checksum .TP .IP "\fBstribog512\fR (added in AIDE v0.17)" GOST R 34.11-2012, 512 bit checksum .TP .IP "md5 (\fBDEPRECATED\fR since AIDE v0.19, will be removed in AIDE v0.21)" MD5 checksum (not in \fIlibgcrypt\fR FIPS mode) .TP .IP "sha1 (\fBDEPRECATED\fR since AIDE v0.19, will be removed in AIDE v0.21)" SHA-1 checksum .TP .IP "rmd160 (\fBDEPRECATED\fR since AIDE v0.19, will be removed in AIDE v0.21)" RIPEMD-160 checksum .TP .IP "gost (\fBDEPRECATED\fR since AIDE v0.19, will be removed in AIDE v0.21)" GOST R 34.11-94 checksum .TP .IP "crc32 (\fBREMOVED\fR in AIDE v0.19)" crc32 checksum .TP .IP "crc32b (\fBREMOVED\fR in AIDE v0.19)" crc32 checksum .TP .IP "haval (\fBREMOVED\fR in AIDE v0.19)" haval256 checksum .TP .IP "tiger (\fBREMOVED\fR in AIDE v0.19)" tiger checksum .TP .IP "whirlpool (\fBREMOVED\fR in AIDE v0.19)" whirlpool checksum .PP Use 'aide --version' to show which hashsums are available. .B Hashsum transitions (since AIDE v0.19): AIDE has limited support for hashsum transitions (i.e. ensuring hashsum validation when hashsums are added/removed from existing entries). If both the old and the new entry do mot share common hashsum(s) AIDE tries to additionally calculate the removed hashsum(s) also for the new entry (this is especieally not supported for moved (\fBI\fR attribute) and compressed (\fBcompressed\fR attribute) entries). .RE .PP .SH EXAMPLES .TP .B "/ R" This adds all files on your machine to the database. This one line is a fully qualified configuration file. .TP .B "!/dev$" This ignores the /dev directory structure. .TP .B "=/foo R" Only /foo and /foobar are taken into the database. None of their children are added. .TP .B "=/foo/ R" Only /foo and its children (e.g. /foo/file and /foo/directory) are taken into the database. The children of sub-directories (e.g. /foo/directory/bar) are not added. .TP .B "/ d,f R" Only add directories and files to the database .TP .B "!/run d" .TQ .B "/run R" Add all but directory entries to the database .TP .B "/run d R-m-c-i" .TQ .B "/run R" Use specific rule for directories .TP Suggested Groups .TP .B "\fBOwnerMode\fR = p+u+g+ftype" Check permissions, owner, group and file type .TP .B "\fBSize\fR = s+b" Check size and block count .TP .B "\fBInodeData\fR = OwnerMode+n+i+Size+l+X" .TQ .B "\fBStaticFile\fR = m+c+Checksums" Files that stay static .PP .B "\fBFull\fR = InodeData+StaticFile" .TQ .B "\fBFull\fR = ftype+p+l+u+g+s+m+c+a+i+b+n+H+X" .TQ .B "/ 0 Full" This line defines group \fBFull\fR. It has all attributes, all compiled in hashsums (\fBH\fR) and all compiled in extra file attributes (\fBX\fR). See '--version' output for the compiled in hashsums and extra groups. The example rule is the typical catch-all rule at the end of the rule list. .TP .B "\fBVarTime\fR = InodeData+Checksums" .TQ .B "/etc/ssl/certs/ca-certificates\e\e.crt$ VarTime" Files that change their mtimes or ctimes but not their contents. .TP .B "\fBVarInode\fR = VarTime-i" .TQ .B "/var/lib/nfs/etab$ f VarInode" Files that are recreated regularly but do not change their contents .TP .B "\fBVarFile\fR = OwnerMode+n+l+X" .TQ .B "/etc/resolv\e\e.conf$ f VarFile" Files that change their contents during system operation .TP .B "\fBVarDir\fR = OwnerMode+n+i+X" .TQ .B "/var/lib/snmp$ d VarDir" Directories that change their contents during system operation .TP .B "\fBRecreatedDir\fR = OwnerMode+n+X" .TQ .B "/run/samba$ d RecreatedDir" Directories that are recreated regularly and change their contents .TP Log Handling .PP Logs pose a number of special challenges to AIDE. An active log is nearly constantly being written to. The process of log rotation changes file names for files that are supposed to have unaltered contents. To save space, Logs are compressed in the process of their rotation, and finally, they get deleted. AIDE is supposed to handle all those cases without generating reports, and it is still expected to flag the cases when an attacker tampers with logs. .PP The following examples suggest a way to handle the common case of log rotation with the logrotate(8) program, with its options \fBcompress\fR, \fBdelaycompress\fR and \fBnocopytruncate\fR set. The vast majority of logs are rotated this way on most Linux systems. .TP .B "\fBActLog\fR=Full+growing+ANF+I" .TQ .B "/var/log/foo\e\e.log$ f ActLog" An Active Log is typically named foo.log. It is constanty being written to. The file does neither change its mode nor its inode number. The size only increases, and what is written to the file is not supposed to change (growing). During log rotation, foo.log is typically renamed to foo.log.1 (or foo.log.0) and the process is instructed to write to a new foo.log. Log content is written to a new file (ANF) and will eventually be renamed to foo.log.1 (I). The growing attribute suppresses reports for files that just had content appended when compared to the database. A change of the old content is still reported! .TP .B "\fBRotLog\fR=Full" .TQ .B "/var/log/foo\e\e.log\e\e.1$ f RotLog" foo.log.0 or foo.log.1 is called the Rotated Log, the previously active log renamed to the first name of the Log Series that is formed by the rotation mechanism. Right after rotation, the file might still being written to by the daemon. To aide, this looks like the Active Log's size decreases and its inode and timestamps change. The Rotated Log is not supposed to change its attributes once the process has stopped writing to it. Reports might be generated if aide runs while the process still writes to the Rotated Log, but this is quite unlikely to happen. Some log rotation mechanisms rename foo.log to foo.log.0 to foo.log.1.gz, others rename foo.log to foo.log.1 to foo.2.log.gz. .TP .B "\fBCompSerLog\fR=Full+I+compressed" .TQ .B "/var/log/foo\e\e.log\e\e.2\e\e.gz$ f CompSerLog" In the next rotation step, foo.log.1 gets compressed to foo.log.2.gz, becoming the Compressed Log in the Log Series. With this rule, AIDE does not report this step because it uncompresses the contents of the file and takes the checksum of the uncompressed content. The contents strictly doesn't change, but some attribute changes are ignored (compressed). .TP .B "\fBMidlSerLog\fR=Full+I" .TQ .B "/var/log/foo\e\e.log\e\e.[345]\e\e.gz$ f MidlSerLog" In the next log rotation, all foo.log.{x} get renamed to foo.log.{x+1}. The other attributes are not supposed to change. .TP .B "\fBLastSerLog\fR=Full+ARF" .TQ .B "/var/log/foo\e\e.log\e\e.6\e\e.gz$ f LastSerLog" The configuration of the log rotation process specifies a number of log generations to keep. The last log in the series is therefore removed from the disk (ARF). .PP aide 0.18 does not yet support the following cases of log rotation: .TP .B "empty files" It might be the case that a log is actually created, but never written to. This commonly happens on rarely used web servers that use the log rotation as a method to cater for data protection regulation. In result, all files in a series are identical, breaking the heuristics that aide uses to detect log rotation. A possible workaround is to begin a newly rotated log with a timestamp. With logrotate, this can be done in a postrotate scriptlet. .TP .B "nodelaycompress" With logrotate's \fBnodelaycompress\fR option, a log is immediately compressed after renaming it from the Active Log name. For the time being, it is recommended to always use the \fBdelaycompress\fR option to avoid this behavior. .TP .B "copytruncate" With logrotate's \fBcopytruncate\fR option, the Active Log is not renamed and newly created but copied to the new file name. After the copy operation, the old file is truncated to zero size, allowing the daemon to continuously write to the already open file handle. aide uses the Inode number to detect the rotation process. That doesn't work with \fBcopytruncate\fR because the Inode stays with the Active Log. For the time being, it is recommended to avoid the \fBcopytruncate\fR option to avoid this behavior. .PP .SH HINTS In the following, the first is not allowed in AIDE. Use the latter instead. .IP .B "/foo epug" .IP .B "/foo e+p+u+g" .PP .SH "SEE ALSO" .BR aide (1) .SH DISCLAIMER All trademarks are the property of their respective owners. No animals were harmed while making this webpage or this piece of software. aide-0.19.3/doc/aide.10000644000175000017500000001645215137354776015513 0ustar00hvhaugwitzhvhaugwitz.TH AIDE 1 "2026-01-31" "aide v0.19.3" "User Commands" .SH NAME \fBaide\fP \- Advanced Intrusion Detection Environment .SH SYNOPSIS \fBaide\fP \%[\fBparameters\fP] \%\fBcommand\fP .SH DESCRIPTION \fBAIDE\fP is an intrusion detection system for checking the integrity of files. .SH COMMANDS .PP .IP "--check, -C" Checks the database for inconsistencies. You must have an initialized database to do this. This is also the default command. Without any command \fBaide\fP does a check. .IP "--init, -i" Initialize the database. You must initialize a database and move it to the appropriate place (see \fBdatabase_in\fR config option) before you can use the \-\-check command. .IP "--dry-init, -n (added in AIDE v0.17)" Traverse the file system, match each file against the rule tree and report to stdout. Neither reports nor the database are written in this mode. To change the log level in this mode please use the \fB--log-level\fR command line parameter. In this mode aide exits with status 0. .IP "--update, -u" Checks the database and updates the database non-interactively. The input and output databases must be different. .IP "--compare, -E" Compares two databases. They must be defined in config file with database= and database_new=. .IP "--list (added in AIDE v0.19)" List the entries of the database in human readable format (analogous to the detailed report output of new files). Note that the checksums are base16 encoded. .IP "--config-check, -D" Stops after reading in the configuration file. Any errors will be reported. To change the log level in this mode please use the \fB--log-level\fR command line parameter. .IP "--path-check=\fIfile_type\fR[=\fIfile_system_type\fR]:\fIpath\fR, -p \fIfile_type\fR[=\fIfile_system_type\fR]:\fIpath\fR (added in AIDE v0.17)" Read configuration and match provided file_type, optionally file system type (added in AIDE v0.19, Linux only) and path against rule tree. The path is independent of what is in the actual file system and needs to be absolute. See RESTRICTED RULES section in aide.conf (5) for supported file types and file system types. Please note that the specified file system type is only applied to the file and not to the parent directories of the path. If a restricted rule cannot be matched against a parent directory due to the missing file system type aide raises a warning. To change the log level in this mode please use the \fB--log-level\fR command line parameter. In this mode aide exits with status 0 if the file would be added to the tree, 1 if not and 2 if the file does not match the specified limit. .SH PARAMETERS .IP "--config=\fBconfigfile\fR , -c \fBconfigfile\fR" Configuration is read from file \fBconfigfile\fR (see \fB--version\fP output for default value). Use '-' for stdin. .IP "--limit=\fBREGEX\fR , -l \fBREGEX\fR (added in AIDE v0.16)" Limit command to entries matching REGEX. Note that the REGEX only matches at the first position. .RS .B Example .RS 3 Only check and update the database entries matching /etc (i.e. the /etc directory) while leaving all other entries unchecked and unchanged: .RS 3 .nf aide --update --limit /etc .fi .RE .RE .RE .IP "--before=\(dq\fBconfigparameters\fR\(dq , -B \(dq\fBconfigparameters\fR\(dq" These \fBconfigparameters\fR are handled before the reading of the configuration file. See aide.conf (5) for more details on what to put here. .IP "--after=\(dq\fBconfigparameters\fR\(dq , -A \(dq\fBconfigparameters\fR\(dq" These \fBconfigparameters\fR are handled after the reading of the configuration file. See aide.conf (5) for more details on what to put here. .IP "--log-level=\fBlog_level\fR,-L\fBlog_level\fR (added in AIDE v0.17)" The log level to use (see aide.conf (5) for available log levels and more details). This overwrites the log_level value set in any configuration file. .IP "--verbose=\fBverbosity_level\fR,-V\fBverbosity_level\fR (REMOVED in AIDE v0.17)" Removed, use \fBlog_level\fR and \fBreport_level\fR config options instead (see aide.conf (5) for details). .IP "--report=\fBreporter\fR,-r \fBreporter\fR (REMOVED in AIDE v0.17)" Removed, use \fBreport_url\fR config option instead (see aide.conf (5) for details). .IP "--workers=\fBWORKERS\fR , -W \fBWORKERS\fR (added in AIDE v0.18)" Specifies the number of workers (see aide.conf (5) for details). This overwrites the num_workers value set in any configuration file. .IP "--no-progress (added in AIDE v0.19)" Turn progress off explicitly. By default progress is shown if standard error is connected to a terminal. .IP "--no-color (added in AIDE v0.19)" Turn colored log output off explicitly. By default colored log output is enabled if standard error is connected to a terminal. .IP "--version,-v" Print version information and exit. .IP "--help,-h" Prints out the standard help message. .PP .SH EXIT STATUS Normally, the exit status is 0 if no errors occurred. Except when the .BR --check , .BR --compare " or" .B --update command was requested, in which case the exit status is defined as: .IP "1 * (new files reported?) +" .IP "2 * (removed files reported?) +" .IP "4 * (changed files reported?)" .PP Since those three cases can occur together, the respective error codes are added. For example, if there are new files and removed files reported, the exit status will be 1 + 2 = 3. .PP Additionally, the following exit codes are defined for generic error conditions: .IP "14 Writing error" .IP "15 Invalid argument error" .IP "16 Unimplemented function error" .IP "17 Configuration error" .IP "18 IO error" .IP "19 Version mismatch error" .IP "20 EXEC error" .IP "21 File lock error" .IP "22 Memory allocation error" .IP "23 Thread error" .IP "24 Database error" .IP "25 received SIGINT, SIGTERM or SIGHUP" .PP .SH SIGNAL HANDLING .IP "\fBSIGINT\fR, \fBSIGTERM\fR, \fBSIGHUP\fR" Remove an incompletely written database (only if database file was created by aide) and exit (code 25). .IP \fBSIGUSR1\fR Toggle the log_level between current and debug level. \fBSIGUSR1\fR is only handled after config parsing. .IP \fBSIGWINCH\fR Resize the progress bar (if enabled). .PP .SH NOTES .IP "Checksum encoding" The checksums in the database and in the output are by default base64 encoded (see also report_base16 option). To decode them you can use the following shell command: echo | base64 \-d | hexdump \-v \-e '32/1 "%02x" "\\n"' .IP "Control characters" Control characters (00-31 and 127) are always escaped in log and plain report output. They are escaped by a literal backslash (\\) followed by exactly 3 digits representing the character in octal notation (e.g. a newline is output as "\fB\\012\fR"). A literal backslash is not escaped unless it is followed by 3 digits (0-9), in this case the literal backslash is escaped as "\fB\\134\fR". Reports in JSON format are escaped according to the JSON specs (e.g. a newline is output as "\fB\\b\fR" or an escape (\fBESC\fR) is output as "\fB\\u001b\fR") .PP .SH FILES See \fB--version\fR output for the default \fBconfig file\fR and the default \fBdatabase_in\fR and \fBdatabase_out\fR config values. .SH SEE ALSO .BR aide.conf (5) .SH BUGS There are probably bugs in this release. Please report them at https://github.com/aide/aide/issues . .SH DISCLAIMER All trademarks are the property of their respective owners. No animals were harmed while making this webpage or this piece of software. Although some pizza delivery guy's feelings were hurt. .BR aide-0.19.3/COPYING0000644000175000017500000004325414412055402014770 0ustar00hvhaugwitzhvhaugwitz GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. aide-0.19.3/src/0000755000175000017500000000000015137355021014521 5ustar00hvhaugwitzhvhaugwitzaide-0.19.3/src/getopt.c0000644000175000017500000007252714412055402016177 0ustar00hvhaugwitzhvhaugwitz/* Getopt for GNU. NOTE: getopt is now part of the C library, so if you don't know what "Keep this file name-space clean" means, talk to drepper@gnu.org before changing it! Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This tells Alpha OSF/1 not to define a getopt prototype in . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #include "aide.h" #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* Comment out all this code if we are using the GNU C Library, and are not actually compiling the library itself. This code is part of the GNU C Library, but also included in many other GNU distributions. Compiling and linking in this code is a waste when using the GNU C library (especially if it is a shared library). Rather than having every GNU program understand `configure --with-gnu-libc' and omit the object files, it is simpler to just do this in the source for each such file. */ #define GETOPT_INTERFACE_VERSION 2 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 # include # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION # define ELIDE_CODE # endif #endif #ifndef ELIDE_CODE /* This needs to come after some library #include to get __GNU_LIBRARY__ defined. */ #ifdef __GNU_LIBRARY__ /* Don't include stdlib.h for non-GNU C libraries because some of them contain conflicting prototypes for getopt. */ # include # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ # ifdef HAVE_LIBINTL_H # include # define _(msgid) gettext (msgid) # else # define _(msgid) (msgid) # endif #endif /* This version of `getopt' appears to the caller like standard Unix `getopt' but it behaves differently for the user, since it allows the user to intersperse the options with the other arguments. As `getopt' works, it permutes the elements of ARGV so that, when it is done, all the options precede everything else. Thus all application programs are extended to handle flexible argument order. Setting the environment variable POSIXLY_CORRECT disables permutation. Then the behavior is completely standard. GNU application programs can use a third alternative mode in which they can distinguish the relative order of options and other arguments. */ #include "getopt.h" /* For communication from `getopt' to the caller. When `getopt' finds an option that takes an argument, the argument value is returned here. Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element is returned here. */ char *optarg = NULL; /* Index in ARGV of the next element to be scanned. This is used for communication to and from the caller and for communication between successive calls to `getopt'. On entry to `getopt', zero means this is the first call; initialize. When `getopt' returns -1, this is the index of the first of the non-option elements that the caller should itself scan. Otherwise, `optind' communicates from one call to the next how much of ARGV has been scanned so far. */ /* 1003.2 says this must be 1 before any call. */ int optind = 1; /* Formerly, initialization of getopt depended on optind==0, which causes problems with re-calling getopt as programs generally don't know that. */ int __getopt_initialized = 0; /* The next char to be scanned in the option-element in which the last option character we returned was found. This allows us to pick up the scan where we left off. If this is zero, or a null string, it means resume the scan by advancing to the next ARGV-element. */ static char *nextchar; /* Callers store zero here to inhibit the error message for unrecognized options. */ int opterr = 1; /* Set to an option character which was unrecognized. This must be initialized on some systems to avoid linking in the system's own getopt implementation. */ int optopt = '?'; /* Describe how to deal with options that follow non-option ARGV-elements. If the caller did not specify anything, the default is REQUIRE_ORDER if the environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise. REQUIRE_ORDER means don't recognize them as options; stop option processing when the first non-option is seen. This is what Unix does. This mode of operation is selected by either setting the environment variable POSIXLY_CORRECT, or using `+' as the first character of the list of option characters. PERMUTE is the default. We permute the contents of ARGV as we scan, so that eventually all the non-options are at the end. This allows options to be given in any order, even with programs that were not written to expect this. RETURN_IN_ORDER is an option available to programs that were written to expect options and other ARGV-elements in any order and that care about the ordering of the two. We describe each non-option ARGV-element as if it were the argument of an option with character code 1. Using `-' as the first character of the list of option characters selects this mode of operation. The special argument `--' forces an end of option-scanning regardless of the value of `ordering'. In the case of RETURN_IN_ORDER, only `--' can cause `getopt' to return -1 with `optind' != ARGC. */ static enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering; /* Value of POSIXLY_CORRECT environment variable. */ static char *posixly_correct; #ifdef __GNU_LIBRARY__ /* We want to avoid inclusion of string.h with non-GNU libraries because there are many ways it can cause trouble. On some systems, it contains special magic macros that don't work in GCC. */ # include # define my_index strchr #else # if HAVE_STRING_H # include # else # include # endif /* Avoid depending on library functions or files whose names are inconsistent. */ #ifndef getenv extern char *getenv (); #endif static char * my_index (str, chr) const char *str; int chr; { while (*str) { if (*str == chr) return (char *) str; str++; } return 0; } /* If using GCC, we can safely declare strlen this way. If not using GCC, it is ok not to declare it. */ #ifdef __GNUC__ /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. That was relevant to code that was here before. */ # if (!defined __STDC__ || !__STDC__) && !defined strlen /* gcc with -traditional declares the built-in strlen to return int, and has done so at least since version 2.4.5. -- rms. */ extern int strlen (const char *); # endif /* not __STDC__ */ #endif /* __GNUC__ */ #endif /* not __GNU_LIBRARY__ */ /* Handle permutation of arguments. */ /* Describe the part of ARGV that contains non-options that have been skipped. `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is the index after the last of them. */ static int first_nonopt; static int last_nonopt; #ifdef _LIBC /* Bash 2.0 gives us an environment variable containing flags indicating ARGV elements that should not be considered arguments. */ /* Defined in getopt_init.c */ extern char *__getopt_nonoption_flags; static int nonoption_flags_max_len; static int nonoption_flags_len; static int original_argc; static char *const *original_argv; /* Make sure the environment variable bash 2.0 puts in the environment is valid for the getopt call we must make sure that the ARGV passed to getopt is that one passed to the process. */ static void __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) { /* XXX This is no good solution. We should rather copy the args so that we can compare them later. But we must not use malloc(3). */ original_argc = argc; original_argv = argv; } # ifdef text_set_element text_set_element (__libc_subinit, store_args_and_env); # endif /* text_set_element */ # define SWAP_FLAGS(ch1, ch2) \ if (nonoption_flags_len > 0) \ { \ char __tmp = __getopt_nonoption_flags[ch1]; \ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ __getopt_nonoption_flags[ch2] = __tmp; \ } #else /* !_LIBC */ # define SWAP_FLAGS(ch1, ch2) #endif /* _LIBC */ /* Exchange two adjacent subsequences of ARGV. One subsequence is elements [first_nonopt,last_nonopt) which contains all the non-options that have been skipped so far. The other is elements [last_nonopt,optind), which contains all the options processed since those non-options were skipped. `first_nonopt' and `last_nonopt' are relocated so that they describe the new indices of the non-options in ARGV after they are moved. */ #if defined __STDC__ && __STDC__ static void exchange (char **); #endif static void exchange (argv) char **argv; { int bottom = first_nonopt; int middle = last_nonopt; int top = optind; char *tem; /* Exchange the shorter segment with the far end of the longer segment. That puts the shorter segment into the right place. It leaves the longer segment in the right place overall, but it consists of two parts that need to be swapped next. */ #ifdef _LIBC /* First make sure the handling of the `__getopt_nonoption_flags' string can work normally. Our top argument must be in the range of the string. */ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) { /* We must extend the array. The user plays games with us and presents new arguments. */ char *new_str = malloc (top + 1); if (new_str == NULL) nonoption_flags_len = nonoption_flags_max_len = 0; else { memset (__mempcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len), '\0', top + 1 - nonoption_flags_max_len); nonoption_flags_max_len = top + 1; __getopt_nonoption_flags = new_str; } } #endif while (top > middle && middle > bottom) { if (top - middle > middle - bottom) { /* Bottom segment is the short one. */ int len = middle - bottom; register int i; /* Swap it with the top part of the top segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[top - (middle - bottom) + i]; argv[top - (middle - bottom) + i] = tem; SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); } /* Exclude the moved bottom segment from further swapping. */ top -= len; } else { /* Top segment is the short one. */ int len = top - middle; register int i; /* Swap it with the bottom part of the bottom segment. */ for (i = 0; i < len; i++) { tem = argv[bottom + i]; argv[bottom + i] = argv[middle + i]; argv[middle + i] = tem; SWAP_FLAGS (bottom + i, middle + i); } /* Exclude the moved top segment from further swapping. */ bottom += len; } } /* Update records for the slots the non-options now occupy. */ first_nonopt += (optind - last_nonopt); last_nonopt = optind; } /* Initialize the internal data when the first call is made. */ #if defined __STDC__ && __STDC__ static const char *_getopt_initialize (int, char *const *, const char *); #endif static const char * _getopt_initialize (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { /* Start processing options with ARGV-element 1 (since ARGV-element 0 is the program name); the sequence of previously skipped non-option ARGV-elements is empty. */ first_nonopt = last_nonopt = optind; nextchar = NULL; posixly_correct = getenv ("POSIXLY_CORRECT"); /* Determine how to handle the ordering of options and nonoptions. */ if (optstring[0] == '-') { ordering = RETURN_IN_ORDER; ++optstring; } else if (optstring[0] == '+') { ordering = REQUIRE_ORDER; ++optstring; } else if (posixly_correct != NULL) ordering = REQUIRE_ORDER; else ordering = PERMUTE; #ifdef _LIBC if (posixly_correct == NULL && argc == original_argc && argv == original_argv) { if (nonoption_flags_max_len == 0) { if (__getopt_nonoption_flags == NULL || __getopt_nonoption_flags[0] == '\0') nonoption_flags_max_len = -1; else { const char *orig_str = __getopt_nonoption_flags; int len = nonoption_flags_max_len = strlen (orig_str); if (nonoption_flags_max_len < argc) nonoption_flags_max_len = argc; __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len); if (__getopt_nonoption_flags == NULL) nonoption_flags_max_len = -1; else memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), '\0', nonoption_flags_max_len - len); } } nonoption_flags_len = nonoption_flags_max_len; } else nonoption_flags_len = 0; #endif return optstring; } /* Scan elements of ARGV (whose length is ARGC) for option characters given in OPTSTRING. If an element of ARGV starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If `getopt' is called repeatedly, it returns successively each of the option characters from each of the option elements. If `getopt' finds another option character, it returns that character, updating `optind' and `nextchar' so that the next call to `getopt' can resume the scan with the following option character or ARGV-element. If there are no more option characters, `getopt' returns -1. Then `optind' is the index in ARGV of the first ARGV-element that is not an option. (The ARGV-elements have been permuted so that those that are not options now come last.) OPTSTRING is a string containing the legitimate option characters. If an option character is seen that is not listed in OPTSTRING, return '?' after printing an error message. If you set `opterr' to zero, the error message is suppressed but we still return '?'. If a char in OPTSTRING is followed by a colon, that means it wants an arg, so the following text in the same ARGV-element, or the text of the following ARGV-element, is returned in `optarg'. Two colons mean an option that wants an optional arg; if there is text in the current ARGV-element, it is returned in `optarg', otherwise `optarg' is set to zero. If OPTSTRING starts with `-' or `+', it requests different methods of handling the non-option ARGV-elements. See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. Long-named options begin with `--' instead of `-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same ARGV-element, separated from the option name by a `=', or else the in next ARGV-element. When `getopt' finds a long-named option, it returns 0 if that option's `flag' field is nonzero, the value of the option's `val' field if the `flag' field is zero. The elements of ARGV aren't really const, because we permute them. But we pretend they're const in the prototype to be compatible with other systems. LONGOPTS is a vector of `struct option' terminated by an element containing a name which is zero. LONGIND returns the index in LONGOPT of the long-named option found. It is only valid when a long-named option has been found by the most recent call. If LONG_ONLY is nonzero, '-' as well as '--' can introduce long-named options. */ int _getopt_internal (argc, argv, optstring, longopts, longind, long_only) int argc; char *const *argv; const char *optstring; const struct option *longopts; int *longind; int long_only; { optarg = NULL; if (optind == 0 || !__getopt_initialized) { if (optind == 0) optind = 1; /* Don't scan ARGV[0], the program name. */ optstring = _getopt_initialize (argc, argv, optstring); __getopt_initialized = 1; } /* Test whether ARGV[optind] points to a non-option argument. Either it does not have option syntax, or there is an environment flag from the shell indicating it is not an option. The later information is only used when the used in the GNU libc. */ #ifdef _LIBC # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ || (optind < nonoption_flags_len \ && __getopt_nonoption_flags[optind] == '1')) #else # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') #endif if (nextchar == NULL || *nextchar == '\0') { /* Advance to the next ARGV-element. */ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been moved back by the user (who may also have changed the arguments). */ if (last_nonopt > optind) last_nonopt = optind; if (first_nonopt > optind) first_nonopt = optind; if (ordering == PERMUTE) { /* If we have just processed some options following some non-options, exchange them so that the options come first. */ if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (last_nonopt != optind) first_nonopt = optind; /* Skip any additional non-options and extend the range of non-options previously skipped. */ while (optind < argc && NONOPTION_P) optind++; last_nonopt = optind; } /* The special ARGV-element `--' means premature end of options. Skip it like a null option, then exchange with previous non-options as if it were an option, then skip everything else like a non-option. */ if (optind != argc && !strcmp (argv[optind], "--")) { optind++; if (first_nonopt != last_nonopt && last_nonopt != optind) exchange ((char **) argv); else if (first_nonopt == last_nonopt) first_nonopt = optind; last_nonopt = argc; optind = argc; } /* If we have done all the ARGV-elements, stop the scan and back over any non-options that we skipped and permuted. */ if (optind == argc) { /* Set the next-arg-index to point at the non-options that we previously skipped, so the caller will digest them. */ if (first_nonopt != last_nonopt) optind = first_nonopt; return -1; } /* If we have come to a non-option and did not permute it, either stop the scan or describe it to the caller and pass it by. */ if (NONOPTION_P) { if (ordering == REQUIRE_ORDER) return -1; optarg = argv[optind++]; return 1; } /* We have found another option-ARGV-element. Skip the initial punctuation. */ nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-')); } /* Decode the current option-ARGV-element. */ /* Check whether the ARGV-element is a long option. If long_only and the ARGV-element has the form "-f", where f is a valid short option, don't consider it an abbreviated form of a long option that starts with f. Otherwise there would be no way to give the -f short option. On the other hand, if there's a long option "fubar" and the ARGV-element is "-fu", do consider that an abbreviation of the long option, just like "--fu", and not "-f" with arg "u". This distinction seems to be the most useful approach. */ if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = -1; int option_index; for (nameend = nextchar; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == (unsigned int) strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; optopt = 0; return '?'; } if (pfound != NULL) { option_index = indfound; optind++; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) { if (argv[optind - 1][1] == '-') /* --option */ fprintf (stderr, _("%s: option `--%s' doesn't allow an argument\n"), argv[0], pfound->name); else /* +option or -option */ fprintf (stderr, _("%s: option `%c%s' doesn't allow an argument\n"), argv[0], argv[optind - 1][0], pfound->name); } nextchar += strlen (nextchar); optopt = pfound->val; return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); optopt = pfound->val; return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } /* Can't find it as a long option. If this is not getopt_long_only, or the option starts with '--' or is not a valid short option, then it's an error. Otherwise interpret it as a short option. */ if (!long_only || argv[optind][1] == '-' || my_index (optstring, *nextchar) == NULL) { if (opterr) { if (argv[optind][1] == '-') /* --option */ fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0], nextchar); else /* +option or -option */ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0], argv[optind][0], nextchar); } nextchar = (char *) ""; optind++; optopt = 0; return '?'; } } /* Look at and handle the next short option-character. */ { char c = *nextchar++; char *temp = my_index (optstring, c); /* Increment `optind' when we start to process its last character. */ if (*nextchar == '\0') ++optind; if (temp == NULL || c == ':') { if (opterr) { if (posixly_correct) /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); else fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c); } optopt = c; return '?'; } /* Convenience. Treat POSIX -W foo same as long option --foo */ if (temp[0] == 'W' && temp[1] == ';') { char *nameend; const struct option *p; const struct option *pfound = NULL; int exact = 0; int ambig = 0; int indfound = 0; int option_index; /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; return c; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; /* optarg is now the argument, see if it's in the table of longopts. */ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) /* Do nothing. */ ; /* Test all long options for either exact match or abbreviated matches. */ for (p = longopts, option_index = 0; p->name; p++, option_index++) if (!strncmp (p->name, nextchar, nameend - nextchar)) { if ((unsigned int) (nameend - nextchar) == strlen (p->name)) { /* Exact match found. */ pfound = p; indfound = option_index; exact = 1; break; } else if (pfound == NULL) { /* First nonexact match found. */ pfound = p; indfound = option_index; } else /* Second or later nonexact match found. */ ambig = 1; } if (ambig && !exact) { if (opterr) fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0], argv[optind]); nextchar += strlen (nextchar); optind++; return '?'; } if (pfound != NULL) { option_index = indfound; if (*nameend) { /* Don't test has_arg with >, because some C compilers don't allow it to be used on enums. */ if (pfound->has_arg) optarg = nameend + 1; else { if (opterr) fprintf (stderr, _("\ %s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name); nextchar += strlen (nextchar); return '?'; } } else if (pfound->has_arg == 1) { if (optind < argc) optarg = argv[optind++]; else { if (opterr) fprintf (stderr, _("%s: option `%s' requires an argument\n"), argv[0], argv[optind - 1]); nextchar += strlen (nextchar); return optstring[0] == ':' ? ':' : '?'; } } nextchar += strlen (nextchar); if (longind != NULL) *longind = option_index; if (pfound->flag) { *(pfound->flag) = pfound->val; return 0; } return pfound->val; } nextchar = NULL; return 'W'; /* Let the application handle it. */ } if (temp[1] == ':') { if (temp[2] == ':') { /* This is an option that accepts an argument optionally. */ if (*nextchar != '\0') { optarg = nextchar; optind++; } else optarg = NULL; nextchar = NULL; } else { /* This is an option that requires an argument. */ if (*nextchar != '\0') { optarg = nextchar; /* If we end this ARGV-element by taking the rest as an arg, we must advance to the next element now. */ optind++; } else if (optind == argc) { if (opterr) { /* 1003.2 specifies the format of this message. */ fprintf (stderr, _("%s: option requires an argument -- %c\n"), argv[0], c); } optopt = c; if (optstring[0] == ':') c = ':'; else c = '?'; } else /* We already incremented `optind' once; increment it again when taking next ARGV-elt as argument. */ optarg = argv[optind++]; nextchar = NULL; } } return c; } } int getopt (argc, argv, optstring) int argc; char *const *argv; const char *optstring; { return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0); } #endif /* Not ELIDE_CODE. */ #ifdef TEST /* Compile with -DTEST to make an executable for use in testing the above definition of `getopt'. */ int main (argc, argv) int argc; char **argv; { int c; int digit_optind = 0; while (1) { int this_option_optind = optind ? optind : 1; c = getopt (argc, argv, "abc:d:0123456789"); if (c == -1) break; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digit_optind != 0 && digit_optind != this_option_optind) printf ("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf ("option %c\n", c); break; case 'a': printf ("option a\n"); break; case 'b': printf ("option b\n"); break; case 'c': printf ("option c with value `%s'\n", optarg); break; case '?': break; default: printf ("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf ("non-option ARGV-elements: "); while (optind < argc) printf ("%s ", argv[optind++]); printf ("\n"); } exit (0); } #endif /* TEST */ aide-0.19.3/src/conf_yacc.c0000644000175000017500000022076415137355020016623 0ustar00hvhaugwitzhvhaugwitz/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ #define YYBISON 30802 /* Bison version string. */ #define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Push parsers. */ #define YYPUSH 0 /* Pull parsers. */ #define YYPULL 1 /* Substitute the variable and function names. */ #define yyparse confparse #define yylex conflex #define yyerror conferror #define yydebug confdebug #define yynerrs confnerrs #define yylval conflval #define yychar confchar /* First part of user prologue. */ #line 4 "src/conf_yacc.y" /* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2006, 2010-2013, 2015-2016, 2019-2025 Rami Lehti, * Pablo Virolainen, Richard van den Berg, Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "attributes.h" #include #include #include "log.h" #include "rx_rule.h" #include "conf_lex.h" DB_ATTR_TYPE retval=0; #include "conf_ast.h" extern int conflex(void); void conferror(ast**, const char *); #line 117 "src/conf_yacc.c" # ifndef YY_CAST # ifdef __cplusplus # define YY_CAST(Type, Val) static_cast (Val) # define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) # else # define YY_CAST(Type, Val) ((Type) (Val)) # define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) # endif # endif # ifndef YY_NULLPTR # if defined __cplusplus # if 201103L <= __cplusplus # define YY_NULLPTR nullptr # else # define YY_NULLPTR 0 # endif # else # define YY_NULLPTR ((void*)0) # endif # endif #include "conf_yacc.h" /* Symbol kind. */ enum yysymbol_kind_t { YYSYMBOL_YYEMPTY = -2, YYSYMBOL_YYEOF = 0, /* "end of file" */ YYSYMBOL_YYerror = 1, /* error */ YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ YYSYMBOL_TDEFINE = 3, /* "@@define" */ YYSYMBOL_TUNDEFINE = 4, /* "@@undef" */ YYSYMBOL_TIFDEF = 5, /* "@@ifdef" */ YYSYMBOL_TIFNDEF = 6, /* "@@ifndef" */ YYSYMBOL_TIFNHOST = 7, /* "@@ifnhost" */ YYSYMBOL_TIFHOST = 8, /* "@@ifhost" */ YYSYMBOL_TIF = 9, /* "@@if" */ YYSYMBOL_TBOOLNOT = 10, /* "not" */ YYSYMBOL_TBOOLFUNC = 11, /* "boolean function" */ YYSYMBOL_TBOOLOP = 12, /* "boolean operator" */ YYSYMBOL_TELSE = 13, /* "@@else" */ YYSYMBOL_TENDIF = 14, /* "@@endif" */ YYSYMBOL_TINCLUDE = 15, /* "@@include" */ YYSYMBOL_TXINCLUDE = 16, /* "@@x_include" */ YYSYMBOL_TSETENV = 17, /* "@@x_include_setenv" */ YYSYMBOL_TGROUP = 18, /* "group name" */ YYSYMBOL_TSTRING = 19, /* "string" */ YYSYMBOL_TEXPR = 20, /* "group" */ YYSYMBOL_TVARIABLE = 21, /* "variable name" */ YYSYMBOL_TSPACE = 22, /* "whitespace" */ YYSYMBOL_TNEWLINE = 23, /* "new line" */ YYSYMBOL_TSELRXRULE = 24, /* "regular rule" */ YYSYMBOL_TEQURXRULE = 25, /* "equals rule" */ YYSYMBOL_TRECNEGRXRULE = 26, /* "recursive negative rule" */ YYSYMBOL_TNONRECNEGRXRULE = 27, /* "non-recursive negative rule" */ YYSYMBOL_CONFIGOPTION = 28, /* "configuration option" */ YYSYMBOL_29_ = 29, /* '+' */ YYSYMBOL_30_ = 30, /* '-' */ YYSYMBOL_31_ = 31, /* ',' */ YYSYMBOL_32_ = 32, /* '=' */ YYSYMBOL_33_0_ = 33, /* '0' */ YYSYMBOL_YYACCEPT = 34, /* $accept */ YYSYMBOL_config = 35, /* config */ YYSYMBOL_statements = 36, /* statements */ YYSYMBOL_statement = 37, /* statement */ YYSYMBOL_attribute_expression = 38, /* attribute_expression */ YYSYMBOL_ft_restriction_expression = 39, /* ft_restriction_expression */ YYSYMBOL_restriction_expression = 40, /* restriction_expression */ YYSYMBOL_define_statement = 41, /* define_statement */ YYSYMBOL_string_expression = 42, /* string_expression */ YYSYMBOL_string_fragment = 43, /* string_fragment */ YYSYMBOL_undefine_statement = 44, /* undefine_statement */ YYSYMBOL_config_statement = 45, /* config_statement */ YYSYMBOL_group_statement = 46, /* group_statement */ YYSYMBOL_include_statement = 47, /* include_statement */ YYSYMBOL_x_include_setenv_statement = 48, /* x_include_setenv_statement */ YYSYMBOL_if_statement = 49, /* if_statement */ YYSYMBOL_if_condition = 50, /* if_condition */ YYSYMBOL_bool_expression = 51, /* bool_expression */ YYSYMBOL_rule_statement = 52 /* rule_statement */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; #ifdef short # undef short #endif /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure and (if available) are included so that the code can choose integer types of a good width. */ #ifndef __PTRDIFF_MAX__ # include /* INFRINGES ON USER NAME SPACE */ # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YY_STDINT_H # endif #endif /* Narrow types that promote to a signed type and that can represent a signed or unsigned integer of at least N bits. In tables they can save space and decrease cache pressure. Promoting to a signed type helps avoid bugs in integer arithmetic. */ #ifdef __INT_LEAST8_MAX__ typedef __INT_LEAST8_TYPE__ yytype_int8; #elif defined YY_STDINT_H typedef int_least8_t yytype_int8; #else typedef signed char yytype_int8; #endif #ifdef __INT_LEAST16_MAX__ typedef __INT_LEAST16_TYPE__ yytype_int16; #elif defined YY_STDINT_H typedef int_least16_t yytype_int16; #else typedef short yytype_int16; #endif /* Work around bug in HP-UX 11.23, which defines these macros incorrectly for preprocessor constants. This workaround can likely be removed in 2023, as HPE has promised support for HP-UX 11.23 (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of . */ #ifdef __hpux # undef UINT_LEAST8_MAX # undef UINT_LEAST16_MAX # define UINT_LEAST8_MAX 255 # define UINT_LEAST16_MAX 65535 #endif #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ && UINT_LEAST8_MAX <= INT_MAX) typedef uint_least8_t yytype_uint8; #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX typedef unsigned char yytype_uint8; #else typedef short yytype_uint8; #endif #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ typedef __UINT_LEAST16_TYPE__ yytype_uint16; #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ && UINT_LEAST16_MAX <= INT_MAX) typedef uint_least16_t yytype_uint16; #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX typedef unsigned short yytype_uint16; #else typedef int yytype_uint16; #endif #ifndef YYPTRDIFF_T # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ # define YYPTRDIFF_T __PTRDIFF_TYPE__ # define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ # elif defined PTRDIFF_MAX # ifndef ptrdiff_t # include /* INFRINGES ON USER NAME SPACE */ # endif # define YYPTRDIFF_T ptrdiff_t # define YYPTRDIFF_MAXIMUM PTRDIFF_MAX # else # define YYPTRDIFF_T long # define YYPTRDIFF_MAXIMUM LONG_MAX # endif #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else # define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM \ YY_CAST (YYPTRDIFF_T, \ (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ ? YYPTRDIFF_MAXIMUM \ : YY_CAST (YYSIZE_T, -1))) #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) /* Stored state numbers (used for stacks). */ typedef yytype_int8 yy_state_t; /* State numbers in computations. */ typedef int yy_state_fast_t; #ifndef YY_ # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ # define YY_(Msgid) Msgid # endif #endif #ifndef YY_ATTRIBUTE_PURE # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) # else # define YY_ATTRIBUTE_PURE # endif #endif #ifndef YY_ATTRIBUTE_UNUSED # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) # define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) # else # define YY_ATTRIBUTE_UNUSED # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YY_USE(E) ((void) (E)) #else # define YY_USE(E) /* empty */ #endif /* Suppress an incorrect diagnostic about yylval being uninitialized. */ #if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ # if __GNUC__ * 100 + __GNUC_MINOR__ < 407 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") # else # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") # endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else # define YY_INITIAL_VALUE(Value) Value #endif #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN # define YY_IGNORE_MAYBE_UNINITIALIZED_END #endif #ifndef YY_INITIAL_VALUE # define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ # define YY_IGNORE_USELESS_CAST_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") # define YY_IGNORE_USELESS_CAST_END \ _Pragma ("GCC diagnostic pop") #endif #ifndef YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_BEGIN # define YY_IGNORE_USELESS_CAST_END #endif #define YY_ASSERT(E) ((void) (0 && (E))) #if 1 /* The parser invokes alloca or malloc; define the necessary symbols. */ # ifdef YYSTACK_USE_ALLOCA # if YYSTACK_USE_ALLOCA # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # elif defined __BUILTIN_VA_ARG_INCR # include /* INFRINGES ON USER NAME SPACE */ # elif defined _AIX # define YYSTACK_ALLOC __alloca # elif defined _MSC_VER # include /* INFRINGES ON USER NAME SPACE */ # define alloca _alloca # else # define YYSTACK_ALLOC alloca # if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's 'empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely invoke alloca (N) if N exceeds 4096. Use a slightly smaller number to allow for a few compiler-allocated temporary stack slots. */ # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ # endif # else # define YYSTACK_ALLOC YYMALLOC # define YYSTACK_FREE YYFREE # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc # if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free # if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif # endif #endif /* 1 */ #if (! defined yyoverflow \ && (! defined __cplusplus \ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { yy_state_t yyss_alloc; YYSTYPE yyvs_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) # define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack_alloc, Stack) \ do \ { \ YYPTRDIFF_T yynewbytes; \ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ Stack = &yyptr->Stack_alloc; \ yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / YYSIZEOF (*yyptr); \ } \ while (0) #endif #if defined YYCOPY_NEEDED && YYCOPY_NEEDED /* Copy COUNT objects from SRC to DST. The source and destination do not overlap. */ # ifndef YYCOPY # if defined __GNUC__ && 1 < __GNUC__ # define YYCOPY(Dst, Src, Count) \ __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) # else # define YYCOPY(Dst, Src, Count) \ do \ { \ YYPTRDIFF_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ #define YYFINAL 51 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 98 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 34 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 19 /* YYNRULES -- Number of rules. */ #define YYNRULES 60 /* YYNSTATES -- Number of states. */ #define YYNSTATES 106 /* YYMAXUTOK -- Last valid token kind. */ #define YYMAXUTOK 283 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM as returned by yylex, with out-of-bounds checking. */ #define YYTRANSLATE(YYX) \ (0 <= (YYX) && (YYX) <= YYMAXUTOK \ ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ : YYSYMBOL_YYUNDEF) /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM as returned by yylex. */ static const yytype_int8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 29, 31, 30, 2, 2, 33, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { 0, 107, 107, 108, 110, 114, 115, 117, 118, 119, 120, 121, 121, 122, 123, 125, 126, 127, 129, 130, 132, 133, 134, 135, 137, 138, 140, 141, 142, 143, 145, 147, 148, 150, 152, 153, 154, 155, 156, 157, 159, 161, 162, 164, 165, 166, 167, 168, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 186 }; #endif /** Accessing symbol of state STATE. */ #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) #if 1 /* The user-facing name of the symbol whose (internal) number is YYSYMBOL. No bounds checking. */ static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "\"end of file\"", "error", "\"invalid token\"", "\"@@define\"", "\"@@undef\"", "\"@@ifdef\"", "\"@@ifndef\"", "\"@@ifnhost\"", "\"@@ifhost\"", "\"@@if\"", "\"not\"", "\"boolean function\"", "\"boolean operator\"", "\"@@else\"", "\"@@endif\"", "\"@@include\"", "\"@@x_include\"", "\"@@x_include_setenv\"", "\"group name\"", "\"string\"", "\"group\"", "\"variable name\"", "\"whitespace\"", "\"new line\"", "\"regular rule\"", "\"equals rule\"", "\"recursive negative rule\"", "\"non-recursive negative rule\"", "\"configuration option\"", "'+'", "'-'", "','", "'='", "'0'", "$accept", "config", "statements", "statement", "attribute_expression", "ft_restriction_expression", "restriction_expression", "define_statement", "string_expression", "string_fragment", "undefine_statement", "config_statement", "group_statement", "include_statement", "x_include_setenv_statement", "if_statement", "if_condition", "bool_expression", "rule_statement", YY_NULLPTR }; static const char * yysymbol_name (yysymbol_kind_t yysymbol) { return yytname[yysymbol]; } #endif #define YYPACT_NINF (-49) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) #define YYTABLE_NINF (-20) #define yytable_value_is_error(Yyn) \ 0 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ static const yytype_int8 yypact[] = { 55, -4, -1, 11, 11, 11, 11, 46, -6, 2, 8, 1, 11, 11, 11, 11, 10, 43, -49, 22, -49, -49, -49, -49, -49, -49, -49, 45, -49, 11, -49, -49, -49, -49, 11, -49, -49, -49, 46, 11, 38, -49, 11, 11, 11, 49, -14, -14, -5, -5, 33, -49, 55, 55, -49, -49, -49, -49, 11, 44, 62, -49, -49, -22, 3, 65, -49, -22, -18, 49, -22, 49, -49, 49, 49, -22, -49, -49, 24, -49, 11, 11, 66, 67, -49, 68, 69, -22, -22, -22, -22, 70, -49, 72, 73, -49, -49, -49, -49, 55, 11, 11, 76, -49, -49, -49 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. Performed when YYTABLE does not specify something else to do. Zero means the default is an error. */ static const yytype_int8 yydefact[] = { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 6, 11, 12, 7, 13, 8, 9, 10, 0, 14, 24, 30, 28, 29, 43, 27, 44, 46, 45, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 53, 54, 0, 1, 5, 0, 25, 26, 48, 49, 0, 34, 37, 40, 17, 33, 17, 0, 23, 51, 22, 0, 52, 0, 19, 57, 58, 32, 31, 4, 0, 50, 0, 0, 0, 0, 21, 0, 0, 55, 56, 59, 60, 0, 41, 35, 38, 15, 16, 18, 20, 0, 0, 0, 0, 36, 39, 42 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -49, -49, -48, -49, -25, -49, 27, -49, -3, -49, -49, -49, -49, -49, -49, -49, -49, 53, -49 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { 0, 17, 18, 19, 63, 68, 69, 20, 40, 34, 21, 22, 23, 24, 25, 26, 27, 41, 28 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule whose number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int8 yytable[] = { 33, 35, 36, 37, 77, 78, 64, 82, 83, 46, 47, 48, 49, 85, 86, 72, 42, 29, 65, 66, 30, 67, 70, -19, 43, 75, 54, 65, 66, 44, 31, 55, 32, 45, -19, -19, 57, 91, 92, 59, 60, 61, 50, 51, 87, 52, 88, 76, 89, 90, 58, 102, 31, 62, 32, 79, 38, 39, 1, 2, 3, 4, 5, 6, 7, 31, 80, 32, 53, 62, 8, 9, 10, 11, 71, 73, 74, 93, 94, 12, 13, 14, 15, 16, 81, 84, 95, 96, 97, 98, 105, 56, 0, 99, 100, 101, 0, 103, 104 }; static const yytype_int8 yycheck[] = { 3, 4, 5, 6, 52, 53, 20, 29, 30, 12, 13, 14, 15, 31, 32, 20, 22, 21, 32, 33, 21, 46, 47, 20, 22, 50, 29, 32, 33, 21, 19, 34, 21, 32, 31, 32, 39, 13, 14, 42, 43, 44, 32, 0, 69, 23, 71, 50, 73, 74, 12, 99, 19, 20, 21, 58, 10, 11, 3, 4, 5, 6, 7, 8, 9, 19, 22, 21, 23, 20, 15, 16, 17, 18, 47, 48, 49, 80, 81, 24, 25, 26, 27, 28, 22, 20, 20, 20, 20, 20, 14, 38, -1, 23, 22, 22, -1, 100, 101 }; /* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of state STATE-NUM. */ static const yytype_int8 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 18, 24, 25, 26, 27, 28, 35, 36, 37, 41, 44, 45, 46, 47, 48, 49, 50, 52, 21, 21, 19, 21, 42, 43, 42, 42, 42, 10, 11, 42, 51, 22, 22, 21, 32, 42, 42, 42, 42, 32, 0, 23, 23, 42, 42, 51, 42, 12, 42, 42, 42, 20, 38, 20, 32, 33, 38, 39, 40, 38, 40, 20, 40, 40, 38, 42, 36, 36, 42, 22, 22, 29, 30, 20, 31, 32, 38, 38, 38, 38, 13, 14, 42, 42, 20, 20, 20, 20, 23, 22, 22, 36, 42, 42, 14 }; /* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int8 yyr1[] = { 0, 34, 35, 35, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 39, 39, 40, 40, 40, 40, 41, 41, 42, 42, 43, 43, 44, 45, 45, 46, 47, 47, 47, 47, 47, 47, 48, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 }; /* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 0, 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, 1, 3, 2, 1, 1, 2, 3, 2, 1, 1, 1, 2, 3, 3, 3, 3, 5, 7, 3, 5, 7, 3, 4, 7, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 2, 2, 4, 4, 3, 3, 4, 4 }; enum { YYENOMEM = -2 }; #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab #define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY) \ { \ yychar = (Token); \ yylval = (Value); \ YYPOPSTACK (yylen); \ yystate = *yyssp; \ goto yybackup; \ } \ else \ { \ yyerror (config_ast, YY_("syntax error: cannot back up")); \ YYERROR; \ } \ while (0) /* Backward compatibility with an undocumented macro. Use YYerror or YYUNDEF. */ #define YYERRCODE YYUNDEF /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yy_symbol_print (stderr, \ Kind, Value, config_ast); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*-----------------------------------. | Print this symbol's value on YYO. | `-----------------------------------*/ static void yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, ast** config_ast) { FILE *yyoutput = yyo; YY_USE (yyoutput); YY_USE (config_ast); if (!yyvaluep) return; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /*---------------------------. | Print this symbol on YYO. | `---------------------------*/ static void yy_symbol_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, ast** config_ast) { YYFPRINTF (yyo, "%s %s (", yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); yy_symbol_value_print (yyo, yykind, yyvaluep, config_ast); YYFPRINTF (yyo, ")"); } /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (included). | `------------------------------------------------------------------*/ static void yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) { int yybot = *yybottom; YYFPRINTF (stderr, " %d", yybot); } YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ static void yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, int yyrule, ast** config_ast) { int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); yy_symbol_print (stderr, YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), &yyvsp[(yyi + 1) - (yynrhs)], config_ast); YYFPRINTF (stderr, "\n"); } } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (yyssp, yyvsp, Rule, config_ast); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) ((void) 0) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif /* Context of a parse error. */ typedef struct { yy_state_t *yyssp; yysymbol_kind_t yytoken; } yypcontext_t; /* Put in YYARG at most YYARGN of the expected tokens given the current YYCTX, and return the number of tokens stored in YYARG. If YYARG is null, return the number of expected tokens (guaranteed to be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. Return 0 if there are more than YYARGN expected tokens, yet fill YYARG up to YYARGN. */ static int yypcontext_expected_tokens (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; int yyn = yypact[+*yyctx->yyssp]; if (!yypact_value_is_default (yyn)) { /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. In other words, skip the first -YYN actions for this state because they are default actions. */ int yyxbegin = yyn < 0 ? -yyn : 0; /* Stay within bounds of both yycheck and yytname. */ int yychecklim = YYLAST - yyn + 1; int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; int yyx; for (yyx = yyxbegin; yyx < yyxend; ++yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYSYMBOL_YYerror && !yytable_value_is_error (yytable[yyx + yyn])) { if (!yyarg) ++yycount; else if (yycount == yyargn) return 0; else yyarg[yycount++] = YY_CAST (yysymbol_kind_t, yyx); } } if (yyarg && yycount == 0 && 0 < yyargn) yyarg[0] = YYSYMBOL_YYEMPTY; return yycount; } #ifndef yystrlen # if defined __GLIBC__ && defined _STRING_H # define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) # else /* Return the length of YYSTR. */ static YYPTRDIFF_T yystrlen (const char *yystr) { YYPTRDIFF_T yylen; for (yylen = 0; yystr[yylen]; yylen++) continue; return yylen; } # endif #endif #ifndef yystpcpy # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * yystpcpy (char *yydest, const char *yysrc) { char *yyd = yydest; const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif #endif #ifndef yytnamerr /* Copy to YYRES the contents of YYSTR after stripping away unnecessary quotes and backslashes, so that it's suitable for yyerror. The heuristic is that double-quoting is unnecessary unless the string contains an apostrophe, a comma, or backslash (other than backslash-backslash). YYSTR is taken from yytname. If YYRES is null, do not copy; instead, return the length of what the result would have been. */ static YYPTRDIFF_T yytnamerr (char *yyres, const char *yystr) { if (*yystr == '"') { YYPTRDIFF_T yyn = 0; char const *yyp = yystr; for (;;) switch (*++yyp) { case '\'': case ',': goto do_not_strip_quotes; case '\\': if (*++yyp != '\\') goto do_not_strip_quotes; else goto append; append: default: if (yyres) yyres[yyn] = *yyp; yyn++; break; case '"': if (yyres) yyres[yyn] = '\0'; return yyn; } do_not_strip_quotes: ; } if (yyres) return yystpcpy (yyres, yystr) - yyres; else return yystrlen (yystr); } #endif static int yy_syntax_error_arguments (const yypcontext_t *yyctx, yysymbol_kind_t yyarg[], int yyargn) { /* Actual size of YYARG. */ int yycount = 0; /* There are many possibilities here to consider: - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected tokens because there are none. - The only way there can be no lookahead present (in yychar) is if this state is a consistent state with a default action. Thus, detecting the absence of a lookahead is sufficient to determine that there is no unexpected or expected token to report. In that case, just report a simple "syntax error". - Don't assume there isn't a lookahead just because this state is a consistent state with a default action. There might have been a previous inconsistent state, consistent state with a non-default action, or user semantic action that manipulated yychar. - Of course, the expected token list depends on states to have correct lookahead information, and it depends on the parser not to perform extra reductions after fetching a lookahead from the scanner and before detecting a syntax error. Thus, state merging (from LALR or IELR) and default reductions corrupt the expected token list. However, the list is correct for canonical LR with one exception: it will still contain any token that will not be accepted due to an error action in a later state. */ if (yyctx->yytoken != YYSYMBOL_YYEMPTY) { int yyn; if (yyarg) yyarg[yycount] = yyctx->yytoken; ++yycount; yyn = yypcontext_expected_tokens (yyctx, yyarg ? yyarg + 1 : yyarg, yyargn - 1); if (yyn == YYENOMEM) return YYENOMEM; else yycount += yyn; } return yycount; } /* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message about the unexpected token YYTOKEN for the state stack whose top is YYSSP. Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is not large enough to hold the message. In that case, also set *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the required number of bytes is too large to store. */ static int yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, const yypcontext_t *yyctx) { enum { YYARGS_MAX = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULLPTR; /* Arguments of yyformat: reported tokens (one for the "unexpected", one per "expected"). */ yysymbol_kind_t yyarg[YYARGS_MAX]; /* Cumulated lengths of YYARG. */ YYPTRDIFF_T yysize = 0; /* Actual size of YYARG. */ int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); if (yycount == YYENOMEM) return YYENOMEM; switch (yycount) { #define YYCASE_(N, S) \ case N: \ yyformat = S; \ break default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); #undef YYCASE_ } /* Compute error message size. Don't count the "%s"s, but reserve room for the terminator. */ yysize = yystrlen (yyformat) - 2 * yycount + 1; { int yyi; for (yyi = 0; yyi < yycount; ++yyi) { YYPTRDIFF_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyarg[yyi]]); if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) yysize = yysize1; else return YYENOMEM; } } if (*yymsg_alloc < yysize) { *yymsg_alloc = 2 * yysize; if (! (yysize <= *yymsg_alloc && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; return -1; } /* Avoid sprintf, as that infringes on the user's name space. Don't have undefined behavior even if the translation produced a string with the wrong number of "%s"s. */ { char *yyp = *yymsg; int yyi = 0; while ((*yyp = *yyformat) != '\0') if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) { yyp += yytnamerr (yyp, yytname[yyarg[yyi++]]); yyformat += 2; } else { ++yyp; ++yyformat; } } return 0; } /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, ast** config_ast) { YY_USE (yyvaluep); YY_USE (config_ast); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } /* Lookahead token kind. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ int yyparse (ast** config_ast) { yy_state_fast_t yystate = 0; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus = 0; /* Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* Their size. */ YYPTRDIFF_T yystacksize = YYINITDEPTH; /* The state stack: array, bottom, top. */ yy_state_t yyssa[YYINITDEPTH]; yy_state_t *yyss = yyssa; yy_state_t *yyssp = yyss; /* The semantic value stack: array, bottom, top. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; YYSTYPE *yyvsp = yyvs; int yyn; /* The return value of yyparse. */ int yyresult; /* Lookahead symbol kind. */ yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* Buffer for error messages, and its allocated size. */ char yymsgbuf[128]; char *yymsg = yymsgbuf; YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ goto yysetstate; /*------------------------------------------------------------. | yynewstate -- push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. So pushing a state here evens the stacks. */ yyssp++; /*--------------------------------------------------------------------. | yysetstate -- set current state (the top of the stack) to yystate. | `--------------------------------------------------------------------*/ yysetstate: YYDPRINTF ((stderr, "Entering state %d\n", yystate)); YY_ASSERT (0 <= yystate && yystate < YYNSTATES); YY_IGNORE_USELESS_CAST_BEGIN *yyssp = YY_CAST (yy_state_t, yystate); YY_IGNORE_USELESS_CAST_END YY_STACK_PRINT (yyss, yyssp); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ YYPTRDIFF_T yysize = yyssp - yyss + 1; # if defined yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ yy_state_t *yyss1 = yyss; YYSTYPE *yyvs1 = yyvs; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow (YY_("memory exhausted"), &yyss1, yysize * YYSIZEOF (*yyssp), &yyvs1, yysize * YYSIZEOF (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { yy_state_t *yyss1 = yyss; union yyalloc *yyptr = YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YY_IGNORE_USELESS_CAST_BEGIN YYDPRINTF ((stderr, "Stack size increased to %ld\n", YY_CAST (long, yystacksize))); YY_IGNORE_USELESS_CAST_END if (yyss + yystacksize - 1 <= yyssp) YYABORT; } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ if (yystate == YYFINAL) YYACCEPT; goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. Read a lookahead token if we need one and don't already have one. */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yypact_value_is_default (yyn)) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token\n")); yychar = yylex (); } if (yychar <= YYEOF) { yychar = YYEOF; yytoken = YYSYMBOL_YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else if (yychar == YYerror) { /* The scanner already issued an error message, process directly to error recovery. But do not keep the error token as lookahead, it is too special and may lead us to an endless loop in error recovery. */ yychar = YYUNDEF; yytoken = YYSYMBOL_YYerror; goto yyerrlab1; } else { yytoken = YYTRANSLATE (yychar); YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yytable_value_is_error (yyn)) goto yyerrlab; yyn = -yyn; goto yyreduce; } /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); yystate = yyn; YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Discard the shifted token. */ yychar = YYEMPTY; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: /* config: statements */ #line 108 "src/conf_yacc.y" { *config_ast = (yyvsp[0].ast); } #line 1498 "src/conf_yacc.c" break; case 4: /* statements: statement "new line" statements */ #line 110 "src/conf_yacc.y" { ast *temp = (yyvsp[-2].ast); temp->next = (yyvsp[0].ast); (yyval.ast) = (yyvsp[-2].ast); } #line 1507 "src/conf_yacc.c" break; case 5: /* statements: statement "new line" */ #line 114 "src/conf_yacc.y" { (yyval.ast) = (yyvsp[-1].ast); } #line 1513 "src/conf_yacc.c" break; case 6: /* statements: statement */ #line 115 "src/conf_yacc.y" { (yyval.ast) = (yyvsp[0].ast); } #line 1519 "src/conf_yacc.c" break; case 15: /* attribute_expression: attribute_expression '+' "group" */ #line 125 "src/conf_yacc.y" { (yyval.attr_expr) = new_attribute_expression(ATTR_OP_PLUS, (yyvsp[-2].attr_expr), (yyvsp[0].s)); } #line 1525 "src/conf_yacc.c" break; case 16: /* attribute_expression: attribute_expression '-' "group" */ #line 126 "src/conf_yacc.y" { (yyval.attr_expr) = new_attribute_expression(ATTR_OP_MINUS, (yyvsp[-2].attr_expr), (yyvsp[0].s)); } #line 1531 "src/conf_yacc.c" break; case 17: /* attribute_expression: "group" */ #line 127 "src/conf_yacc.y" { (yyval.attr_expr) = new_attribute_expression(ATTR_OP_GROUP, NULL, (yyvsp[0].s)); } #line 1537 "src/conf_yacc.c" break; case 18: /* ft_restriction_expression: ft_restriction_expression ',' "group" */ #line 129 "src/conf_yacc.y" { (yyval.ft_rs_expr) = new_ft_restriction_expression((yyvsp[-2].ft_rs_expr), (yyvsp[0].s)); } #line 1543 "src/conf_yacc.c" break; case 19: /* ft_restriction_expression: "group" */ #line 130 "src/conf_yacc.y" { (yyval.ft_rs_expr) = new_ft_restriction_expression(NULL, (yyvsp[0].s)); } #line 1549 "src/conf_yacc.c" break; case 20: /* restriction_expression: ft_restriction_expression '=' "group" */ #line 132 "src/conf_yacc.y" { (yyval.rs_expr) = new_restriction_expression((yyvsp[-2].ft_rs_expr), (yyvsp[0].s)); } #line 1555 "src/conf_yacc.c" break; case 21: /* restriction_expression: '=' "group" */ #line 133 "src/conf_yacc.y" { (yyval.rs_expr) = new_restriction_expression(NULL, (yyvsp[0].s)); } #line 1561 "src/conf_yacc.c" break; case 22: /* restriction_expression: ft_restriction_expression */ #line 134 "src/conf_yacc.y" { (yyval.rs_expr) = new_restriction_expression((yyvsp[0].ft_rs_expr), NULL); } #line 1567 "src/conf_yacc.c" break; case 23: /* restriction_expression: '0' */ #line 135 "src/conf_yacc.y" { (yyval.rs_expr) = new_restriction_expression(NULL, NULL); } #line 1573 "src/conf_yacc.c" break; case 24: /* define_statement: "@@define" "variable name" */ #line 137 "src/conf_yacc.y" { (yyval.ast) = new_define_statement((yyvsp[0].s), NULL); } #line 1579 "src/conf_yacc.c" break; case 25: /* define_statement: "@@define" "variable name" string_expression */ #line 138 "src/conf_yacc.y" { (yyval.ast) = new_define_statement((yyvsp[-1].s), (yyvsp[0].string_expr)); } #line 1585 "src/conf_yacc.c" break; case 26: /* string_expression: string_fragment string_expression */ #line 140 "src/conf_yacc.y" { (yyval.string_expr) = new_string_concat((yyvsp[-1].string_expr), (yyvsp[0].string_expr)); } #line 1591 "src/conf_yacc.c" break; case 27: /* string_expression: string_fragment */ #line 141 "src/conf_yacc.y" { (yyval.string_expr) = (yyvsp[0].string_expr); } #line 1597 "src/conf_yacc.c" break; case 28: /* string_fragment: "string" */ #line 142 "src/conf_yacc.y" { (yyval.string_expr) = new_string((yyvsp[0].s)); } #line 1603 "src/conf_yacc.c" break; case 29: /* string_fragment: "variable name" */ #line 143 "src/conf_yacc.y" { (yyval.string_expr) = new_variable((yyvsp[0].s)); } #line 1609 "src/conf_yacc.c" break; case 30: /* undefine_statement: "@@undef" "variable name" */ #line 145 "src/conf_yacc.y" { (yyval.ast) = new_undefine_statement((yyvsp[0].s)); } #line 1615 "src/conf_yacc.c" break; case 31: /* config_statement: "configuration option" '=' string_expression */ #line 147 "src/conf_yacc.y" { (yyval.ast) = new_string_option_statement((yyvsp[-2].option), (yyvsp[0].string_expr)); } #line 1621 "src/conf_yacc.c" break; case 32: /* config_statement: "configuration option" '=' attribute_expression */ #line 148 "src/conf_yacc.y" { (yyval.ast) = new_attribute_option_statement((yyvsp[-2].option), (yyvsp[0].attr_expr)); } #line 1627 "src/conf_yacc.c" break; case 33: /* group_statement: "group name" '=' attribute_expression */ #line 150 "src/conf_yacc.y" { (yyval.ast) = new_group_statement((yyvsp[-2].s), (yyvsp[0].attr_expr)); } #line 1633 "src/conf_yacc.c" break; case 34: /* include_statement: "@@include" "whitespace" string_expression */ #line 152 "src/conf_yacc.y" { (yyval.ast) = new_include_statement((yyvsp[0].string_expr), NULL, false, NULL); } #line 1639 "src/conf_yacc.c" break; case 35: /* include_statement: "@@include" "whitespace" string_expression "whitespace" string_expression */ #line 153 "src/conf_yacc.y" { (yyval.ast) = new_include_statement((yyvsp[-2].string_expr), (yyvsp[0].string_expr), false, NULL); } #line 1645 "src/conf_yacc.c" break; case 36: /* include_statement: "@@include" "whitespace" string_expression "whitespace" string_expression "whitespace" string_expression */ #line 154 "src/conf_yacc.y" { (yyval.ast) = new_include_statement((yyvsp[-4].string_expr), (yyvsp[-2].string_expr), false, (yyvsp[0].string_expr)); } #line 1651 "src/conf_yacc.c" break; case 37: /* include_statement: "@@x_include" "whitespace" string_expression */ #line 155 "src/conf_yacc.y" { (yyval.ast) = new_include_statement((yyvsp[0].string_expr), NULL, true, NULL); } #line 1657 "src/conf_yacc.c" break; case 38: /* include_statement: "@@x_include" "whitespace" string_expression "whitespace" string_expression */ #line 156 "src/conf_yacc.y" { (yyval.ast) = new_include_statement((yyvsp[-2].string_expr), (yyvsp[0].string_expr), true, NULL); } #line 1663 "src/conf_yacc.c" break; case 39: /* include_statement: "@@x_include" "whitespace" string_expression "whitespace" string_expression "whitespace" string_expression */ #line 157 "src/conf_yacc.y" { (yyval.ast) = new_include_statement((yyvsp[-4].string_expr), (yyvsp[-2].string_expr), true, (yyvsp[0].string_expr)); } #line 1669 "src/conf_yacc.c" break; case 40: /* x_include_setenv_statement: "@@x_include_setenv" "variable name" string_expression */ #line 159 "src/conf_yacc.y" { (yyval.ast) = new_x_include_setenv_statement((yyvsp[-1].s), (yyvsp[0].string_expr)); } #line 1675 "src/conf_yacc.c" break; case 41: /* if_statement: if_condition "new line" statements "@@endif" */ #line 161 "src/conf_yacc.y" { (yyval.ast) = new_if_statement((yyvsp[-3].if_cond), (yyvsp[-1].ast), NULL); } #line 1681 "src/conf_yacc.c" break; case 42: /* if_statement: if_condition "new line" statements "@@else" "new line" statements "@@endif" */ #line 162 "src/conf_yacc.y" { (yyval.ast) = new_if_statement((yyvsp[-6].if_cond), (yyvsp[-4].ast), (yyvsp[-1].ast)); } #line 1687 "src/conf_yacc.c" break; case 43: /* if_condition: "@@ifdef" string_expression */ #line 164 "src/conf_yacc.y" { (yyval.if_cond)=new_if_condition(new_string_bool_expression(BOOL_OP_DEFINED, (yyvsp[0].string_expr), NULL)); } #line 1693 "src/conf_yacc.c" break; case 44: /* if_condition: "@@ifndef" string_expression */ #line 165 "src/conf_yacc.y" { (yyval.if_cond)=new_if_condition(new_bool_expression(BOOL_OP_NOT, new_string_bool_expression(BOOL_OP_DEFINED, (yyvsp[0].string_expr), NULL), NULL)); } #line 1699 "src/conf_yacc.c" break; case 45: /* if_condition: "@@ifhost" string_expression */ #line 166 "src/conf_yacc.y" { (yyval.if_cond)=new_if_condition(new_string_bool_expression(BOOL_OP_HOSTNAME, (yyvsp[0].string_expr), NULL)); } #line 1705 "src/conf_yacc.c" break; case 46: /* if_condition: "@@ifnhost" string_expression */ #line 167 "src/conf_yacc.y" { (yyval.if_cond)=new_if_condition(new_bool_expression(BOOL_OP_NOT, new_string_bool_expression(BOOL_OP_HOSTNAME, (yyvsp[0].string_expr), NULL), NULL)); } #line 1711 "src/conf_yacc.c" break; case 47: /* if_condition: "@@if" bool_expression */ #line 168 "src/conf_yacc.y" { (yyval.if_cond)=new_if_condition((yyvsp[0].bool_expr)); } #line 1717 "src/conf_yacc.c" break; case 48: /* bool_expression: "not" bool_expression */ #line 170 "src/conf_yacc.y" { (yyval.bool_expr) = new_bool_expression(BOOL_OP_NOT, (yyvsp[0].bool_expr), NULL); } #line 1723 "src/conf_yacc.c" break; case 49: /* bool_expression: "boolean function" string_expression */ #line 171 "src/conf_yacc.y" { (yyval.bool_expr) = new_string_bool_expression((yyvsp[-1].operator), (yyvsp[0].string_expr), NULL); } #line 1729 "src/conf_yacc.c" break; case 50: /* bool_expression: string_expression "boolean operator" string_expression */ #line 172 "src/conf_yacc.y" { (yyval.bool_expr) = new_string_bool_expression((yyvsp[-1].operator), (yyvsp[-2].string_expr), (yyvsp[0].string_expr)); } #line 1735 "src/conf_yacc.c" break; case 51: /* rule_statement: "regular rule" string_expression attribute_expression */ #line 174 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_SELECTIVE_RULE, (yyvsp[-1].string_expr), NULL, (yyvsp[0].attr_expr)); } #line 1741 "src/conf_yacc.c" break; case 52: /* rule_statement: "equals rule" string_expression attribute_expression */ #line 175 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_EQUAL_RULE, (yyvsp[-1].string_expr), NULL, (yyvsp[0].attr_expr)); } #line 1747 "src/conf_yacc.c" break; case 53: /* rule_statement: "recursive negative rule" string_expression */ #line 176 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_RECURSIVE_NEGATIVE_RULE, (yyvsp[0].string_expr), NULL, NULL); } #line 1753 "src/conf_yacc.c" break; case 54: /* rule_statement: "non-recursive negative rule" string_expression */ #line 177 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_NON_RECURSIVE_NEGATIVE_RULE, (yyvsp[0].string_expr), NULL, NULL); } #line 1759 "src/conf_yacc.c" break; case 55: /* rule_statement: "regular rule" string_expression restriction_expression attribute_expression */ #line 178 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_SELECTIVE_RULE, (yyvsp[-2].string_expr), (yyvsp[-1].rs_expr), (yyvsp[0].attr_expr)); } #line 1765 "src/conf_yacc.c" break; case 56: /* rule_statement: "equals rule" string_expression restriction_expression attribute_expression */ #line 179 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_EQUAL_RULE, (yyvsp[-2].string_expr), (yyvsp[-1].rs_expr), (yyvsp[0].attr_expr)); } #line 1771 "src/conf_yacc.c" break; case 57: /* rule_statement: "recursive negative rule" string_expression restriction_expression */ #line 180 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_RECURSIVE_NEGATIVE_RULE, (yyvsp[-1].string_expr), (yyvsp[0].rs_expr), NULL); } #line 1777 "src/conf_yacc.c" break; case 58: /* rule_statement: "non-recursive negative rule" string_expression restriction_expression */ #line 181 "src/conf_yacc.y" { (yyval.ast) = new_rule_statement(AIDE_NON_RECURSIVE_NEGATIVE_RULE, (yyvsp[-1].string_expr), (yyvsp[0].rs_expr), NULL); } #line 1783 "src/conf_yacc.c" break; case 59: /* rule_statement: "recursive negative rule" string_expression restriction_expression attribute_expression */ #line 182 "src/conf_yacc.y" { log_msg(LOG_LEVEL_ERROR, "%s:%d: recursive negative rule must not have an attribute expression (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); YYABORT; } #line 1792 "src/conf_yacc.c" break; case 60: /* rule_statement: "non-recursive negative rule" string_expression restriction_expression attribute_expression */ #line 186 "src/conf_yacc.y" { log_msg(LOG_LEVEL_ERROR, "%s:%d: non-recursive negative rule must not have an attribute expression (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); YYABORT; } #line 1801 "src/conf_yacc.c" break; #line 1805 "src/conf_yacc.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires that yytoken be updated with the new translation. We take the approach of translating immediately before every use of yytoken. One alternative is translating here after every semantic action, but that translation would be missed if the semantic action invokes YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an incorrect destructor might then be invoked immediately. In the case of YYERROR or YYBACKUP, subsequent parser actions might lead to an incorrect destructor call or verbose syntax error message before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); YYPOPSTACK (yylen); yylen = 0; *++yyvsp = yyval; /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ { const int yylhs = yyr1[yyn] - YYNTOKENS; const int yyi = yypgoto[yylhs] + *yyssp; yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp ? yytable[yyi] : yydefgoto[yylhs]); } goto yynewstate; /*--------------------------------------. | yyerrlab -- here on detecting error. | `--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; { yypcontext_t yyctx = {yyssp, yytoken}; char const *yymsgp = YY_("syntax error"); int yysyntax_error_status; yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); if (yysyntax_error_status == 0) yymsgp = yymsg; else if (yysyntax_error_status == -1) { if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); yymsg = YY_CAST (char *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); if (yymsg) { yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); yymsgp = yymsg; } else { yymsg = yymsgbuf; yymsg_alloc = sizeof yymsgbuf; yysyntax_error_status = YYENOMEM; } } yyerror (config_ast, yymsgp); if (yysyntax_error_status == YYENOMEM) YYNOMEM; } } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ if (yychar <= YYEOF) { /* Return failure if at end of input. */ if (yychar == YYEOF) YYABORT; } else { yydestruct ("Error: discarding", yytoken, &yylval, config_ast); yychar = YYEMPTY; } } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*---------------------------------------------------. | yyerrorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ yyerrorlab: /* Pacify compilers when the user code never invokes YYERROR and the label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; YY_STACK_PRINT (yyss, yyssp); yystate = *yyssp; goto yyerrlab1; /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ /* Pop stack until we find a state that shifts the error token. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) { yyn += YYSYMBOL_YYerror; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; yydestruct ("Error: popping", YY_ACCESSING_SYMBOL (yystate), yyvsp, config_ast); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturnlab; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturnlab; /*-----------------------------------------------------------. | yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | `-----------------------------------------------------------*/ yyexhaustedlab: yyerror (config_ast, YY_("memory exhausted")); yyresult = 2; goto yyreturnlab; /*----------------------------------------------------------. | yyreturnlab -- parsing is finished, clean up and return. | `----------------------------------------------------------*/ yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ yytoken = YYTRANSLATE (yychar); yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval, config_ast); } /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, config_ast); YYPOPSTACK (1); } #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); return yyresult; } #line 191 "src/conf_yacc.y" void conferror( ast** config_ast __attribute__((unused)), const char *msg){ log_msg(LOG_LEVEL_ERROR, "%s:%d: %s (line: '%s')", conf_filename, conf_linenumber, msg, conf_linebuf); } aide-0.19.3/src/tree.c0000644000175000017500000000720614774422002015631 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2023 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "tree.h" #include "util.h" struct tree_node { void *key; void *data; long unsigned level; struct tree_node *parent; struct tree_node *left; struct tree_node *right; }; static tree_node *tree_new_node(void *key, tree_node *parent) { tree_node *n = checked_malloc(sizeof(tree_node)); n->key = key; n->data = NULL; n->level = 1; n->parent = parent; n->left = NULL; n->right = NULL; return n; } /* implements an AA tree, a simplified red-black tree */ static tree_node *_insert(tree_node *n, tree_node *parent, void *key, void *data, tree_cmp_f compare) { if (n == NULL) { n = tree_new_node(key, parent); n->data = data; return n; } int c = compare(key, n->key); if (c < 0) { n->left = _insert(n->left, n, key, data, compare); } else if (c > 0) { n->right = _insert(n->right, n, key, data, compare); } if (n != NULL && n->left != NULL && n->level == (n->left)->level) { tree_node *l = n->left; n->left = l->right; if (n->left) { (n->left)->parent = n; } l->right = n; l->parent = n->parent; n->parent = l; n = l; } if (n != NULL && n->right != NULL && (n->right)->right != NULL && n->level == ((n->right)->right)->level) { tree_node *r = n->right; n->right = r->left; if (n->right) { (n->right)->parent = n; } r->left = n; r->parent = n->parent; n->parent = r; r->level++; n = r; } return n; } tree_node *tree_insert(tree_node *root, void *key, void * data, tree_cmp_f compare) { root = _insert(root, NULL, key, data, compare); root->parent = NULL; return root; } void *tree_search(tree_node *root, void *key, int (*compare) (const void*, const void*)) { if (root == NULL) { return NULL; } tree_node *n = root; int c; while (n != NULL && (c = compare(key, n->key)) != 0) { if (c < 0) { n = n->left; } else { n = n->right; } } return n?n->data:NULL; } tree_node *tree_walk_first(tree_node *root) { tree_node *n = root; if (n) { if (n->left) { while (n->left != NULL) { n = n->left; } } } return n; } tree_node *tree_walk_next(tree_node *m) { if (m != NULL) { if (m->right != NULL) { m = m->right; while (m->left) { m = m->left; } } else { while (m->parent != NULL && (m->parent)->right == m) { m = m->parent; } m = m->parent; } } return m; } void *tree_get_data(tree_node *n) { return n->data; } aide-0.19.3/src/conf_lex.c0000644000175000017500000026235115137355020016472 0ustar00hvhaugwitzhvhaugwitz#line 2 "src/conf_lex.c" #line 4 "src/conf_lex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define yy_create_buffer conf_create_buffer #define yy_delete_buffer conf_delete_buffer #define yy_scan_buffer conf_scan_buffer #define yy_scan_string conf_scan_string #define yy_scan_bytes conf_scan_bytes #define yy_init_buffer conf_init_buffer #define yy_flush_buffer conf_flush_buffer #define yy_load_buffer_state conf_load_buffer_state #define yy_switch_to_buffer conf_switch_to_buffer #define yypush_buffer_state confpush_buffer_state #define yypop_buffer_state confpop_buffer_state #define yyensure_buffer_stack confensure_buffer_stack #define yy_flex_debug conf_flex_debug #define yyin confin #define yyleng confleng #define yylex conflex #define yylineno conflineno #define yyout confout #define yyrestart confrestart #define yytext conftext #define yywrap confwrap #define yyalloc confalloc #define yyrealloc confrealloc #define yyfree conffree #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 6 #define YY_FLEX_SUBMINOR_VERSION 4 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif #ifdef yy_create_buffer #define conf_create_buffer_ALREADY_DEFINED #else #define yy_create_buffer conf_create_buffer #endif #ifdef yy_delete_buffer #define conf_delete_buffer_ALREADY_DEFINED #else #define yy_delete_buffer conf_delete_buffer #endif #ifdef yy_scan_buffer #define conf_scan_buffer_ALREADY_DEFINED #else #define yy_scan_buffer conf_scan_buffer #endif #ifdef yy_scan_string #define conf_scan_string_ALREADY_DEFINED #else #define yy_scan_string conf_scan_string #endif #ifdef yy_scan_bytes #define conf_scan_bytes_ALREADY_DEFINED #else #define yy_scan_bytes conf_scan_bytes #endif #ifdef yy_init_buffer #define conf_init_buffer_ALREADY_DEFINED #else #define yy_init_buffer conf_init_buffer #endif #ifdef yy_flush_buffer #define conf_flush_buffer_ALREADY_DEFINED #else #define yy_flush_buffer conf_flush_buffer #endif #ifdef yy_load_buffer_state #define conf_load_buffer_state_ALREADY_DEFINED #else #define yy_load_buffer_state conf_load_buffer_state #endif #ifdef yy_switch_to_buffer #define conf_switch_to_buffer_ALREADY_DEFINED #else #define yy_switch_to_buffer conf_switch_to_buffer #endif #ifdef yypush_buffer_state #define confpush_buffer_state_ALREADY_DEFINED #else #define yypush_buffer_state confpush_buffer_state #endif #ifdef yypop_buffer_state #define confpop_buffer_state_ALREADY_DEFINED #else #define yypop_buffer_state confpop_buffer_state #endif #ifdef yyensure_buffer_stack #define confensure_buffer_stack_ALREADY_DEFINED #else #define yyensure_buffer_stack confensure_buffer_stack #endif #ifdef yylex #define conflex_ALREADY_DEFINED #else #define yylex conflex #endif #ifdef yyrestart #define confrestart_ALREADY_DEFINED #else #define yyrestart confrestart #endif #ifdef yylex_init #define conflex_init_ALREADY_DEFINED #else #define yylex_init conflex_init #endif #ifdef yylex_init_extra #define conflex_init_extra_ALREADY_DEFINED #else #define yylex_init_extra conflex_init_extra #endif #ifdef yylex_destroy #define conflex_destroy_ALREADY_DEFINED #else #define yylex_destroy conflex_destroy #endif #ifdef yyget_debug #define confget_debug_ALREADY_DEFINED #else #define yyget_debug confget_debug #endif #ifdef yyset_debug #define confset_debug_ALREADY_DEFINED #else #define yyset_debug confset_debug #endif #ifdef yyget_extra #define confget_extra_ALREADY_DEFINED #else #define yyget_extra confget_extra #endif #ifdef yyset_extra #define confset_extra_ALREADY_DEFINED #else #define yyset_extra confset_extra #endif #ifdef yyget_in #define confget_in_ALREADY_DEFINED #else #define yyget_in confget_in #endif #ifdef yyset_in #define confset_in_ALREADY_DEFINED #else #define yyset_in confset_in #endif #ifdef yyget_out #define confget_out_ALREADY_DEFINED #else #define yyget_out confget_out #endif #ifdef yyset_out #define confset_out_ALREADY_DEFINED #else #define yyset_out confset_out #endif #ifdef yyget_leng #define confget_leng_ALREADY_DEFINED #else #define yyget_leng confget_leng #endif #ifdef yyget_text #define confget_text_ALREADY_DEFINED #else #define yyget_text confget_text #endif #ifdef yyget_lineno #define confget_lineno_ALREADY_DEFINED #else #define yyget_lineno confget_lineno #endif #ifdef yyset_lineno #define confset_lineno_ALREADY_DEFINED #else #define yyset_lineno confset_lineno #endif #ifdef yywrap #define confwrap_ALREADY_DEFINED #else #define yywrap confwrap #endif #ifdef yyalloc #define confalloc_ALREADY_DEFINED #else #define yyalloc confalloc #endif #ifdef yyrealloc #define confrealloc_ALREADY_DEFINED #else #define yyrealloc confrealloc #endif #ifdef yyfree #define conffree_ALREADY_DEFINED #else #define yyfree conffree #endif #ifdef yytext #define conftext_ALREADY_DEFINED #else #define yytext conftext #endif #ifdef yyleng #define confleng_ALREADY_DEFINED #else #define yyleng confleng #endif #ifdef yyin #define confin_ALREADY_DEFINED #else #define yyin confin #endif #ifdef yyout #define confout_ALREADY_DEFINED #else #define yyout confout #endif #ifdef yy_flex_debug #define conf_flex_debug_ALREADY_DEFINED #else #define yy_flex_debug conf_flex_debug #endif #ifdef yylineno #define conflineno_ALREADY_DEFINED #else #define yylineno conflineno #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #ifndef SIZE_MAX #define SIZE_MAX (~(size_t)0) #endif #endif /* ! C99 */ #endif /* ! FLEXINT_H */ /* begin standard C++ headers. */ /* TODO: this is always defined, so inline it */ #define yyconst const #if defined(__GNUC__) && __GNUC__ >= 3 #define yynoreturn __attribute__((__noreturn__)) #else #define yynoreturn #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an * integer in range [0..255] for use as an array index. */ #define YY_SC_TO_UI(c) ((YY_CHAR) (c)) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart( yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k. * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. * Ditto for the __ia64__ case accordingly. */ #define YY_BUF_SIZE 32768 #else #define YY_BUF_SIZE 16384 #endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) #define YY_LINENO_REWIND_TO(ptr) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ int yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = NULL; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart ( FILE *input_file ); void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); void yy_delete_buffer ( YY_BUFFER_STATE b ); void yy_flush_buffer ( YY_BUFFER_STATE b ); void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); void yypop_buffer_state ( void ); static void yyensure_buffer_stack ( void ); static void yy_load_buffer_state ( void ); static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); void *yyalloc ( yy_size_t ); void *yyrealloc ( void *, yy_size_t ); void yyfree ( void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer( yyin, YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef flex_uint8_t YY_CHAR; FILE *yyin = NULL, *yyout = NULL; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #ifdef yytext_ptr #undef yytext_ptr #endif #define yytext_ptr yytext static yy_state_type yy_get_previous_state ( void ); static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); static int yy_get_next_buffer ( void ); static void yynoreturn yy_fatal_error ( const char* msg ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (int) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 80 #define YY_END_OF_BUFFER 81 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static const flex_int16_t yy_accept[494] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 79, 80, 3, 3, 2, 79, 3, 36, 78, 79, 79, 4, 66, 79, 6, 65, 79, 79, 65, 65, 65, 65, 65, 65, 65, 65, 65, 16, 35, 11, 12, 14, 13, 10, 15, 79, 9, 69, 75, 71, 71, 73, 72, 79, 67, 77, 76, 25, 25, 25, 25, 25, 25, 74, 3, 3, 2, 0, 3, 3, 1, 0, 36, 78, 7, 4, 66, 8, 65, 5, 0, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 16, 35, 35, 11, 0, 9, 9, 69, 75, 0, 70, 73, 72, 0, 67, 67, 76, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 0, 0, 0, 0, 20, 0, 0, 0, 0, 19, 0, 0, 0, 66, 65, 65, 65, 66, 66, 65, 65, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, 65, 66, 64, 64, 65, 66, 66, 68, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 64, 65, 65, 64, 64, 64, 65, 64, 64, 0, 23, 0, 0, 0, 29, 26, 0, 0, 0, 0, 18, 0, 66, 66, 65, 64, 64, 64, 66, 64, 64, 21, 0, 0, 17, 30, 27, 0, 0, 0, 64, 64, 64, 65, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 22, 0, 31, 32, 0, 64, 64, 64, 66, 64, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 0, 64, 64, 64, 64, 64, 64, 64, 59, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 53, 64, 66, 24, 33, 64, 64, 64, 64, 64, 37, 64, 64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 60, 64, 0, 64, 64, 64, 64, 64, 39, 38, 64, 66, 64, 64, 64, 64, 64, 46, 56, 64, 64, 0, 64, 66, 64, 66, 64, 57, 55, 64, 66, 45, 64, 64, 64, 64, 0, 64, 64, 61, 64, 40, 64, 64, 42, 66, 64, 64, 0, 66, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 64, 64, 64, 66, 64, 64, 64, 66, 64, 64, 64, 0, 64, 64, 64, 64, 64, 64, 64, 66, 64, 66, 64, 34, 64, 66, 64, 64, 50, 64, 64, 66, 64, 64, 41, 64, 64, 64, 64, 64, 64, 66, 64, 64, 64, 64, 64, 54, 66, 64, 66, 64, 64, 44, 64, 52, 64, 64, 66, 64, 64, 64, 64, 66, 66, 66, 64, 64, 64, 64, 58, 64, 64, 64, 64, 64, 64, 43, 64, 47, 64, 64, 64, 64, 64, 64, 49, 48, 64, 64, 64, 66, 64, 64, 64, 64, 62, 0 } ; static const YY_CHAR yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 1, 7, 1, 8, 1, 1, 1, 1, 1, 9, 10, 11, 1, 12, 13, 14, 15, 16, 16, 16, 17, 16, 16, 16, 1, 1, 1, 18, 19, 1, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 1, 23, 1, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 1, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 8, 1, 1, 8, 1, 1, 1, 1, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 8, 1, 1, 1 } ; static const YY_CHAR yy_meta[52] = { 0, 1, 2, 3, 3, 2, 1, 1, 4, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 6, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1 } ; static const flex_int16_t yy_base[513] = { 0, 855, 0, 7, 0, 58, 109, 160, 0, 211, 262, 68, 78, 85, 120, 130, 134, 223, 232, 88, 99, 95, 141, 312, 356, 236, 274, 857, 859, 859, 0, 244, 859, 853, 71, 146, 859, 852, 842, 0, 0, 841, 859, 71, 840, 831, 394, 413, 812, 825, 799, 809, 802, 57, 821, 0, 272, 0, 859, 859, 859, 0, 859, 214, 839, 0, 153, 823, 237, 248, 288, 265, 837, 859, 290, 859, 813, 793, 801, 800, 809, 295, 0, 299, 859, 833, 295, 304, 859, 832, 316, 859, 859, 0, 0, 859, 118, 859, 297, 429, 0, 799, 796, 789, 799, 800, 793, 789, 789, 785, 0, 317, 337, 0, 304, 820, 819, 0, 318, 773, 859, 333, 340, 350, 817, 816, 360, 791, 787, 776, 774, 775, 361, 787, 112, 282, 777, 790, 445, 789, 782, 786, 770, 785, 784, 768, 762, 767, 0, 771, 760, 758, 859, 758, 770, 756, 770, 340, 770, 768, 762, 207, 761, 767, 768, 313, 107, 749, 766, 765, 736, 749, 742, 747, 751, 750, 753, 748, 751, 740, 342, 742, 748, 738, 736, 743, 748, 347, 743, 732, 726, 287, 349, 859, 740, 725, 742, 727, 727, 859, 734, 733, 719, 732, 721, 714, 728, 730, 732, 731, 711, 727, 706, 709, 726, 707, 719, 719, 859, 709, 707, 715, 859, 859, 699, 712, 698, 712, 859, 703, 304, 352, 709, 698, 707, 700, 446, 705, 708, 859, 703, 707, 859, 859, 859, 686, 700, 683, 678, 694, 696, 700, 678, 686, 692, 680, 694, 689, 678, 674, 684, 685, 668, 667, 669, 680, 681, 859, 677, 859, 859, 679, 669, 676, 662, 357, 659, 0, 660, 661, 657, 655, 656, 658, 658, 649, 661, 656, 656, 658, 666, 660, 659, 651, 659, 642, 355, 646, 654, 637, 0, 638, 651, 650, 653, 255, 632, 637, 646, 645, 636, 0, 624, 305, 859, 647, 637, 634, 635, 639, 622, 0, 618, 620, 0, 625, 647, 628, 631, 634, 618, 615, 620, 611, 629, 0, 604, 609, 613, 626, 610, 624, 605, 0, 0, 618, 627, 608, 619, 598, 612, 611, 0, 0, 597, 601, 608, 601, 333, 597, 363, 591, 0, 0, 604, 367, 0, 604, 607, 597, 593, 584, 603, 601, 0, 596, 0, 596, 579, 0, 390, 572, 588, 591, 377, 577, 574, 593, 572, 587, 582, 597, 583, 582, 572, 571, 569, 569, 581, 373, 563, 576, 578, 572, 564, 576, 564, 552, 561, 572, 567, 556, 550, 563, 553, 547, 550, 362, 545, 859, 551, 380, 561, 552, 0, 556, 552, 557, 535, 548, 0, 540, 540, 533, 532, 551, 545, 529, 536, 539, 501, 494, 465, 0, 399, 460, 442, 457, 446, 0, 454, 0, 437, 456, 436, 451, 442, 425, 422, 409, 422, 415, 435, 414, 415, 412, 0, 411, 409, 408, 406, 404, 398, 0, 408, 0, 394, 384, 393, 370, 362, 349, 0, 0, 336, 310, 282, 43, 216, 220, 129, 59, 0, 859, 490, 496, 502, 508, 514, 520, 526, 532, 538, 544, 547, 549, 551, 553, 1, 555, 561, 564, 566 } ; static const flex_int16_t yy_def[513] = { 0, 494, 495, 493, 3, 496, 496, 493, 7, 497, 497, 494, 494, 498, 498, 498, 498, 498, 498, 494, 494, 499, 499, 500, 500, 498, 498, 493, 493, 493, 501, 501, 493, 493, 502, 493, 493, 493, 493, 503, 504, 493, 493, 505, 493, 493, 506, 506, 47, 47, 47, 47, 47, 47, 47, 507, 508, 509, 493, 493, 493, 509, 493, 493, 493, 510, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 501, 501, 493, 493, 502, 502, 493, 493, 493, 493, 493, 503, 504, 493, 505, 493, 493, 511, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 507, 508, 508, 509, 493, 493, 493, 510, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 511, 47, 47, 47, 47, 47, 47, 47, 47, 47, 512, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 138, 47, 47, 47, 138, 138, 47, 47, 47, 512, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 138, 47, 47, 138, 138, 138, 47, 138, 138, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 138, 47, 47, 138, 138, 138, 47, 138, 138, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 138, 138, 47, 138, 138, 138, 138, 138, 138, 493, 493, 493, 493, 493, 493, 493, 493, 493, 138, 138, 138, 47, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 493, 493, 493, 493, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 493, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 493, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 493, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 504, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493 } ; static const flex_int16_t yy_nxt[911] = { 0, 493, 31, 32, 33, 31, 112, 34, 28, 35, 36, 37, 35, 38, 39, 40, 28, 28, 41, 42, 43, 43, 43, 43, 43, 44, 28, 45, 43, 28, 40, 46, 47, 48, 49, 47, 47, 50, 47, 47, 47, 47, 51, 47, 52, 47, 47, 47, 53, 47, 47, 47, 47, 54, 47, 47, 47, 28, 28, 28, 35, 36, 37, 35, 28, 28, 94, 28, 28, 28, 28, 36, 37, 63, 88, 89, 28, 28, 28, 94, 28, 36, 37, 63, 488, 107, 64, 66, 36, 37, 66, 36, 37, 71, 94, 108, 64, 74, 36, 37, 74, 492, 36, 37, 71, 67, 72, 68, 28, 28, 28, 35, 36, 37, 35, 28, 28, 72, 28, 28, 28, 28, 66, 36, 37, 66, 94, 28, 28, 28, 94, 28, 69, 36, 37, 69, 69, 36, 37, 69, 67, 94, 68, 74, 36, 37, 74, 155, 90, 156, 67, 90, 68, 189, 67, 118, 68, 491, 118, 28, 28, 28, 35, 36, 37, 35, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 56, 28, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 28, 28, 28, 35, 36, 37, 35, 28, 28, 114, 58, 59, 60, 28, 61, 70, 36, 37, 70, 62, 94, 28, 115, 28, 70, 36, 37, 70, 81, 29, 28, 81, 120, 67, 184, 68, 83, 84, 85, 83, 121, 86, 67, 121, 68, 490, 67, 120, 68, 120, 489, 28, 28, 28, 35, 36, 37, 35, 28, 28, 123, 58, 59, 60, 28, 61, 81, 29, 28, 81, 62, 328, 28, 124, 28, 111, 111, 111, 111, 111, 122, 329, 126, 122, 67, 126, 68, 132, 88, 89, 132, 83, 84, 85, 83, 487, 86, 88, 89, 114, 94, 157, 28, 28, 35, 29, 28, 35, 90, 158, 118, 90, 115, 118, 133, 134, 215, 94, 94, 135, 111, 111, 111, 111, 111, 121, 94, 486, 121, 76, 77, 136, 122, 78, 137, 122, 248, 336, 188, 79, 111, 111, 111, 111, 111, 123, 94, 80, 35, 29, 28, 35, 126, 132, 485, 126, 132, 178, 124, 203, 94, 179, 94, 204, 211, 94, 216, 180, 249, 373, 94, 296, 319, 76, 77, 94, 94, 78, 429, 297, 94, 378, 484, 79, 298, 299, 94, 250, 320, 375, 94, 80, 94, 94, 483, 411, 396, 96, 96, 96, 96, 96, 482, 94, 389, 96, 390, 99, 391, 481, 101, 94, 94, 452, 432, 480, 96, 96, 96, 96, 96, 392, 94, 465, 96, 479, 99, 94, 94, 467, 478, 477, 94, 94, 94, 94, 94, 476, 475, 474, 94, 473, 94, 94, 472, 471, 470, 469, 94, 94, 94, 94, 94, 468, 466, 464, 94, 463, 99, 94, 255, 256, 462, 257, 461, 258, 259, 460, 260, 459, 458, 261, 457, 456, 455, 454, 262, 453, 263, 451, 264, 28, 28, 28, 28, 28, 28, 30, 30, 30, 30, 30, 30, 55, 55, 55, 55, 55, 55, 57, 57, 57, 57, 57, 57, 65, 65, 65, 65, 65, 65, 73, 73, 73, 73, 73, 73, 75, 75, 75, 75, 75, 75, 82, 82, 450, 82, 82, 82, 87, 87, 87, 87, 87, 87, 93, 93, 449, 93, 93, 93, 94, 94, 96, 96, 100, 100, 110, 110, 113, 113, 113, 117, 448, 447, 117, 117, 117, 138, 138, 170, 170, 446, 445, 444, 443, 442, 441, 440, 439, 438, 437, 436, 435, 434, 433, 431, 430, 428, 427, 426, 425, 424, 423, 422, 421, 420, 419, 418, 417, 416, 415, 414, 413, 412, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 399, 398, 397, 395, 394, 393, 388, 387, 386, 385, 384, 383, 382, 381, 380, 379, 377, 376, 374, 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, 362, 361, 360, 359, 358, 357, 356, 355, 354, 353, 352, 351, 350, 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, 339, 338, 337, 335, 334, 333, 332, 331, 330, 327, 326, 325, 324, 323, 322, 321, 318, 317, 316, 315, 314, 313, 312, 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, 301, 300, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 277, 276, 275, 274, 273, 272, 271, 270, 269, 268, 267, 266, 265, 254, 253, 252, 251, 247, 246, 245, 244, 243, 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, 223, 222, 221, 220, 219, 218, 217, 214, 213, 212, 210, 209, 208, 207, 206, 205, 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 187, 186, 185, 183, 182, 181, 177, 176, 175, 174, 173, 172, 171, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, 159, 154, 153, 152, 151, 150, 149, 125, 125, 148, 116, 116, 147, 146, 145, 144, 143, 142, 141, 140, 139, 88, 84, 131, 130, 129, 128, 127, 125, 119, 116, 109, 106, 105, 104, 103, 102, 98, 97, 95, 92, 91, 84, 493, 29, 27, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493 } ; static const flex_int16_t yy_chk[911] = { 0, 0, 2, 2, 2, 2, 508, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 487, 5, 5, 5, 5, 11, 11, 11, 34, 34, 5, 5, 5, 43, 5, 12, 12, 12, 487, 53, 11, 13, 13, 13, 13, 19, 19, 19, 43, 53, 12, 21, 21, 21, 21, 491, 20, 20, 20, 13, 19, 13, 5, 5, 6, 6, 6, 6, 6, 6, 6, 20, 6, 6, 6, 6, 14, 14, 14, 14, 96, 6, 6, 6, 166, 6, 15, 15, 15, 15, 16, 16, 16, 16, 14, 96, 14, 22, 22, 22, 22, 134, 35, 134, 15, 35, 15, 166, 16, 66, 16, 490, 66, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 63, 9, 9, 9, 9, 9, 17, 17, 17, 17, 9, 161, 9, 63, 9, 18, 18, 18, 18, 25, 25, 25, 25, 68, 17, 161, 17, 31, 31, 31, 31, 69, 31, 18, 69, 18, 489, 25, 68, 25, 68, 488, 9, 9, 10, 10, 10, 10, 10, 10, 10, 71, 10, 10, 10, 10, 10, 26, 26, 26, 26, 10, 305, 10, 71, 10, 56, 56, 56, 56, 56, 70, 305, 74, 70, 26, 74, 26, 81, 86, 86, 81, 83, 83, 83, 83, 486, 83, 87, 87, 114, 191, 135, 10, 10, 23, 23, 23, 23, 90, 135, 118, 90, 114, 118, 98, 98, 191, 230, 313, 98, 111, 111, 111, 111, 111, 121, 165, 485, 121, 23, 23, 98, 122, 23, 98, 122, 230, 313, 165, 23, 112, 112, 112, 112, 112, 123, 358, 23, 24, 24, 24, 24, 126, 132, 484, 126, 132, 157, 123, 180, 187, 157, 192, 180, 187, 231, 192, 157, 231, 358, 275, 275, 296, 24, 24, 417, 360, 24, 417, 275, 365, 365, 481, 24, 275, 275, 399, 231, 296, 360, 384, 24, 46, 421, 480, 399, 384, 46, 46, 46, 46, 46, 479, 380, 380, 46, 380, 46, 380, 478, 46, 47, 444, 444, 421, 477, 47, 47, 47, 47, 47, 380, 459, 459, 47, 476, 47, 99, 461, 461, 474, 472, 99, 99, 99, 99, 99, 471, 470, 469, 99, 468, 99, 138, 467, 465, 464, 463, 138, 138, 138, 138, 138, 462, 460, 458, 138, 457, 138, 236, 236, 236, 456, 236, 455, 236, 236, 454, 236, 453, 452, 236, 450, 448, 447, 446, 236, 445, 236, 442, 236, 494, 494, 494, 494, 494, 494, 495, 495, 495, 495, 495, 495, 496, 496, 496, 496, 496, 496, 497, 497, 497, 497, 497, 497, 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 500, 500, 500, 500, 500, 500, 501, 501, 441, 501, 501, 501, 502, 502, 502, 502, 502, 502, 503, 503, 440, 503, 503, 503, 504, 504, 505, 505, 506, 506, 507, 507, 509, 509, 509, 510, 439, 438, 510, 510, 510, 511, 511, 512, 512, 437, 436, 435, 434, 433, 432, 431, 429, 428, 427, 426, 425, 423, 422, 420, 418, 416, 415, 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, 404, 403, 402, 401, 400, 398, 397, 396, 395, 394, 393, 392, 391, 390, 389, 388, 387, 386, 385, 383, 382, 381, 378, 377, 375, 373, 372, 371, 370, 369, 368, 367, 364, 361, 359, 357, 356, 355, 354, 351, 350, 349, 348, 347, 346, 345, 342, 341, 340, 339, 338, 337, 336, 334, 333, 332, 331, 330, 329, 328, 327, 326, 325, 323, 322, 320, 319, 318, 317, 316, 315, 312, 310, 309, 308, 307, 306, 304, 303, 302, 301, 299, 298, 297, 295, 294, 293, 292, 291, 290, 289, 288, 287, 286, 285, 284, 283, 282, 281, 280, 279, 278, 276, 274, 273, 272, 271, 268, 266, 265, 264, 263, 262, 261, 260, 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 241, 240, 238, 237, 235, 234, 233, 232, 229, 227, 226, 225, 224, 221, 220, 219, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200, 198, 197, 196, 195, 194, 190, 189, 188, 186, 185, 184, 183, 182, 181, 179, 178, 177, 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, 164, 163, 162, 160, 159, 158, 156, 155, 154, 153, 151, 150, 149, 147, 146, 145, 144, 143, 142, 141, 140, 139, 137, 136, 133, 131, 130, 129, 128, 127, 125, 124, 119, 116, 115, 109, 108, 107, 106, 105, 104, 103, 102, 101, 89, 85, 80, 79, 78, 77, 76, 72, 67, 64, 54, 52, 51, 50, 49, 48, 45, 44, 41, 38, 37, 33, 27, 1, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, 493 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "src/conf_lex.l" #line 9 "src/conf_lex.l" #define YYDEBUG 1 /* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2002, 2004-2006, 2010-2013, 2015-2016, 2019-2025 * Rami Lehti, Pablo Virolainen, Richard van den Berg, * Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "util.h" #include "conf_yacc.h" #include "errorcodes.h" #include "commandconf.h" #include "log.h" #include "progress.h" #include "conf_ast.h" #define LOG_LEX_TOKEN(log_level, token, text) \ log_msg(log_level, "%s:%d: \u2502 " #token " (text: '%s')", conf_filename, conf_linenumber, text); #define LOG_CONFIG_LINE(log_level, msg) \ log_msg(log_level, "%s:%d: %s (line: '%s')", conf_filename, conf_linenumber, msg, conf_linebuf); #define DEPRECATION_NOTICE(deprecated_option, new_option) \ log_msg(LOG_LEVEL_NOTICE, "%s:%d: Using '%s' is DEPRECATED and will be removed in the release after next. Update your config and use '%s' instead (line: '%s')", conf_filename, conf_linenumber, deprecated_option, new_option ,conf_linebuf); #define DEPRECATION_WARNING(deprecated_option, new_option) \ log_msg(LOG_LEVEL_WARNING, "%s:%d: Using '%s' is DEPRECATED and will be removed in the next release.. Update your config and use '%s' instead (line: '%s')", conf_filename, conf_linenumber, deprecated_option, new_option ,conf_linebuf); int conf_linenumber = 0; char *conf_filename; char *conf_linebuf; LOG_LEVEL lex_log_level = LOG_LEVEL_DEBUG; #define YY_INPUT(buf,result,max_size) \ if( ((result=conf_input_wrapper(buf,max_size,confin)) == 0) \ && ferror(yyin) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); #line 1127 "src/conf_lex.c" #define YY_NO_INPUT 1 #line 1130 "src/conf_lex.c" #define INITIAL 0 #define CONFIG 1 #define DEFSTMT 2 #define ENVVAR 3 #define EXPR 4 #define EXPREQUHUNT 5 #define PATH 6 #define STRING 7 #define STRINGS 8 #define STRINGEQHUNT 9 #define STRINGHUNT 10 #define CONDITION 11 #define CONDSTRING 12 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals ( void ); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int yylex_destroy ( void ); int yyget_debug ( void ); void yyset_debug ( int debug_flag ); YY_EXTRA_TYPE yyget_extra ( void ); void yyset_extra ( YY_EXTRA_TYPE user_defined ); FILE *yyget_in ( void ); void yyset_in ( FILE * _in_str ); FILE *yyget_out ( void ); void yyset_out ( FILE * _out_str ); int yyget_leng ( void ); char *yyget_text ( void ); int yyget_lineno ( void ); void yyset_lineno ( int _line_number ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap ( void ); #else extern int yywrap ( void ); #endif #endif #ifndef YY_NO_UNPUT #endif #ifndef yytext_ptr static void yy_flex_strncpy ( char *, const char *, int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen ( const char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput ( void ); #else static int input ( void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #ifdef __ia64__ /* On IA-64, the buffer size is 16k, not 8k */ #define YY_READ_BUF_SIZE 16384 #else #define YY_READ_BUF_SIZE 8192 #endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK /*LINTED*/break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { yy_state_type yy_current_state; char *yy_cp, *yy_bp; int yy_act; if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_load_buffer_state( ); } { #line 71 "src/conf_lex.l" #line 1362 "src/conf_lex.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); yy_match: do { YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 494 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 859 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case YY_STATE_EOF(INITIAL): #line 72 "src/conf_lex.l" { log_msg(lex_log_level,"%s: - ", conf_filename); return (0); } YY_BREAK case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 76 "src/conf_lex.l" { conf_linebuf = checked_strndup(conftext, confleng-1); ++conf_linenumber; LOG_CONFIG_LINE(lex_log_level, "- skip comment line") free(conf_linebuf); } YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 82 "src/conf_lex.l" { conf_linebuf = ""; ++conf_linenumber; LOG_CONFIG_LINE(lex_log_level, "- skip empty line") } YY_BREAK case 3: YY_RULE_SETUP #line 87 "src/conf_lex.l" { conf_linebuf = checked_strndup(conftext, confleng); ++conf_linenumber; log_msg(lex_log_level,"%s:%d: \u252c '%s'", conf_filename, conf_linenumber, conf_linebuf); yyless(0); BEGIN(CONFIG); } YY_BREAK case 4: YY_RULE_SETUP #line 94 "src/conf_lex.l" { /* inline comment */ LOG_LEX_TOKEN(lex_log_level, skip inline comment, conftext) } YY_BREAK case 5: YY_RULE_SETUP #line 98 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TEQURXRULE, "=") yyless(strchr(conftext,'/')-conftext); BEGIN(PATH); return (TEQURXRULE); } YY_BREAK case 6: YY_RULE_SETUP #line 105 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TSELRXRULE, "") yyless(strchr(conftext,'/')-conftext); BEGIN(PATH); return (TSELRXRULE); } YY_BREAK case 7: YY_RULE_SETUP #line 112 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TRECNEGRXRULE, "!") yyless(strchr(conftext,'/')-conftext); BEGIN(PATH); return (TRECNEGRXRULE); } YY_BREAK case 8: YY_RULE_SETUP #line 119 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TNONRECNEGRXRULE, "-") yyless(strchr(conftext,'/')-conftext); BEGIN(PATH); return (TNONRECNEGRXRULE); } YY_BREAK case 9: YY_RULE_SETUP #line 126 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, '=', conftext) BEGIN(EXPR); return('='); } YY_BREAK case 10: YY_RULE_SETUP #line 132 "src/conf_lex.l" { /* no restriction */ LOG_LEX_TOKEN(lex_log_level, '0', conftext) return ('0'); } YY_BREAK case 11: YY_RULE_SETUP #line 137 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TEXPR, conftext) conflval.s=checked_strdup(conftext); return (TEXPR); } YY_BREAK case 12: YY_RULE_SETUP #line 143 "src/conf_lex.l" { /* attribute operator */ LOG_LEX_TOKEN(lex_log_level, '+', conftext) return ('+'); } YY_BREAK case 13: YY_RULE_SETUP #line 148 "src/conf_lex.l" { /* attribute operator */ LOG_LEX_TOKEN(lex_log_level, '-', conftext) return ('-'); } YY_BREAK case 14: YY_RULE_SETUP #line 153 "src/conf_lex.l" { /* restriction separator */ LOG_LEX_TOKEN(lex_log_level, ',', conftext) return (','); } YY_BREAK case 15: YY_RULE_SETUP #line 158 "src/conf_lex.l" { /* restriction file system type separator */ LOG_LEX_TOKEN(lex_log_level, '=', conftext) return ('='); } YY_BREAK case 16: YY_RULE_SETUP #line 163 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conftext) conflval.s=checked_strdup(conftext); BEGIN(STRINGHUNT); return (TVARIABLE); } YY_BREAK case 17: YY_RULE_SETUP #line 170 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TDEFINE, conftext) BEGIN DEFSTMT; return (TDEFINE); } YY_BREAK case 18: YY_RULE_SETUP #line 176 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TUNDEFINE, conftext) BEGIN DEFSTMT; return (TUNDEFINE); } YY_BREAK case 19: YY_RULE_SETUP #line 182 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TIF, conftext) BEGIN(CONDITION); return (TIF); } YY_BREAK case 20: YY_RULE_SETUP #line 188 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TBOOLNOT, conftext) return (TBOOLNOT); } YY_BREAK case 21: YY_RULE_SETUP #line 193 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TBOOLFUNC (BOOL_OP_DEFINED), conftext) conflval.operator = BOOL_OP_DEFINED; BEGIN(STRINGHUNT); return (TBOOLFUNC); } YY_BREAK case 22: YY_RULE_SETUP #line 200 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TBOOLFUNC (BOOL_OP_HOSTNAME), conftext) conflval.operator = BOOL_OP_HOSTNAME; BEGIN(STRINGHUNT); return (TBOOLFUNC); } YY_BREAK case 23: YY_RULE_SETUP #line 207 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TBOOLFUNC (BOOL_OP_EXISTS), conftext) conflval.operator = BOOL_OP_EXISTS; BEGIN(STRINGHUNT); return (TBOOLFUNC); } YY_BREAK case 24: YY_RULE_SETUP #line 214 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TBOOLOP (BOOL_OP_VERSION_GE), conftext) conflval.operator = BOOL_OP_VERSION_GE; BEGIN(STRINGHUNT); return (TBOOLOP); } YY_BREAK case 25: YY_RULE_SETUP #line 221 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, found string -> unput, conftext) yyless(0); BEGIN(CONDSTRING); } YY_BREAK case 26: YY_RULE_SETUP #line 227 "src/conf_lex.l" { DEPRECATION_WARNING("@@ifdef", "@@if defined") LOG_LEX_TOKEN(lex_log_level, TIFDEF, conftext) BEGIN(STRINGHUNT); return (TIFDEF); } YY_BREAK case 27: YY_RULE_SETUP #line 234 "src/conf_lex.l" { DEPRECATION_WARNING("@@ifndef", "@@if not defined") LOG_LEX_TOKEN(lex_log_level, TIFNDEF, conftext) BEGIN(STRINGHUNT); return (TIFNDEF); } YY_BREAK case 28: YY_RULE_SETUP #line 241 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TELSE, conftext) BEGIN CONFIG; return (TELSE); } YY_BREAK case 29: YY_RULE_SETUP #line 247 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TENDIF, conftext) BEGIN CONFIG; return (TENDIF); } YY_BREAK case 30: YY_RULE_SETUP #line 253 "src/conf_lex.l" { DEPRECATION_WARNING("@@ifhost", "@@if hostname") LOG_LEX_TOKEN(lex_log_level, TIFHOST, conftext) BEGIN(STRINGHUNT); return (TIFHOST); } YY_BREAK case 31: YY_RULE_SETUP #line 260 "src/conf_lex.l" { DEPRECATION_WARNING("@@ifnhost", "@@if not hostname") LOG_LEX_TOKEN(lex_log_level, TIFNHOST, conftext) BEGIN(STRINGHUNT); return (TIFNHOST); } YY_BREAK case 32: YY_RULE_SETUP #line 267 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TINCLUDE, conftext) BEGIN(STRINGS); return (TINCLUDE); } YY_BREAK case 33: YY_RULE_SETUP #line 273 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TXINCLUDE, conftext) BEGIN(STRINGS); return (TXINCLUDE); } YY_BREAK case 34: YY_RULE_SETUP #line 279 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TSETENV, conftext) BEGIN ENVVAR; return (TSETENV); } YY_BREAK case 35: YY_RULE_SETUP #line 285 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conftext) conflval.s=checked_strdup(conftext); BEGIN(STRINGHUNT); return (TVARIABLE); } YY_BREAK case 36: YY_RULE_SETUP #line 292 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext) } YY_BREAK case 37: YY_RULE_SETUP #line 296 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_IN_OPTION), conftext) conflval.option = DATABASE_IN_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 38: YY_RULE_SETUP #line 303 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_OUT_OPTION), conftext) conflval.option = DATABASE_OUT_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 39: YY_RULE_SETUP #line 310 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_NEW_OPTION), conftext) conflval.option = DATABASE_NEW_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 40: YY_RULE_SETUP #line 317 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_ATTRIBUTES_OPTION), conftext) conflval.option = DATABASE_ATTRIBUTES_OPTION; BEGIN (EXPREQUHUNT); return (CONFIGOPTION); } YY_BREAK case 41: YY_RULE_SETUP #line 324 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (WARN_DEAD_SYMLINKS_OPTION), conftext) conflval.option = WARN_DEAD_SYMLINKS_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 42: YY_RULE_SETUP #line 331 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_GROUPED_OPTION), conftext) conflval.option = REPORT_GROUPED_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 43: YY_RULE_SETUP #line 338 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_SUMMARIZE_CHANGES_OPTION), conftext) conflval.option = REPORT_SUMMARIZE_CHANGES_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 44: YY_RULE_SETUP #line 344 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (ACL_NO_SYMLINK_FOLLOW_OPTION), conftext) conflval.option = ACL_NO_SYMLINK_FOLLOW_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 45: YY_RULE_SETUP #line 351 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_FORMAT_OPTION), conftext) conflval.option = REPORT_FORMAT_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 46: YY_RULE_SETUP #line 358 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_LEVEL_OPTION), conftext) conflval.option = REPORT_LEVEL_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 47: YY_RULE_SETUP #line 365 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_ADDED_ATTRS_OPTION), conftext) conflval.option = REPORT_IGNORE_ADDED_ATTRS_OPTION; BEGIN (EXPREQUHUNT); return (CONFIGOPTION); } YY_BREAK case 48: YY_RULE_SETUP #line 372 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_REMOVED_ATTRS_OPTION), conftext) conflval.option = REPORT_IGNORE_REMOVED_ATTRS_OPTION; BEGIN (EXPREQUHUNT); return (CONFIGOPTION); } YY_BREAK case 49: YY_RULE_SETUP #line 379 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_CHANGED_ATTRS_OPTION), conftext) conflval.option = REPORT_IGNORE_CHANGED_ATTRS_OPTION; BEGIN (EXPREQUHUNT); return (CONFIGOPTION); } YY_BREAK case 50: YY_RULE_SETUP #line 386 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_FORCE_ATTRS_OPTION), conftext) conflval.option = REPORT_FORCE_ATTRS_OPTION; BEGIN (EXPREQUHUNT); return (CONFIGOPTION); } YY_BREAK case 51: YY_RULE_SETUP #line 393 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (LOG_LEVEL_OPTION), conftext) conflval.option = LOG_LEVEL_OPTION; BEGIN(STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 52: YY_RULE_SETUP #line 400 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_ADD_METADATA_OPTION), conftext) conflval.option = DATABASE_ADD_METADATA_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 53: YY_RULE_SETUP #line 407 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_URL_OPTION), conftext) conflval.option = REPORT_URL_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 54: YY_RULE_SETUP #line 414 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_DETAILED_INIT_OPTION), conftext) conflval.option = REPORT_DETAILED_INIT_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 55: YY_RULE_SETUP #line 421 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_BASE16_OPTION), conftext) conflval.option = REPORT_BASE16_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 56: YY_RULE_SETUP #line 428 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_QUIET_OPTION), conftext) conflval.option = REPORT_QUIET_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 57: YY_RULE_SETUP #line 435 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_APPEND_OPTION), conftext) conflval.option = REPORT_APPEND_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 58: YY_RULE_SETUP #line 442 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (REPORT_IGNORE_E2FSATTRS_OPTION), conftext) conflval.option = REPORT_IGNORE_E2FSATTRS_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 59: YY_RULE_SETUP #line 449 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (DATABASE_GZIP_OPTION), conftext) conflval.option = DATABASE_GZIP_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 60: YY_RULE_SETUP #line 456 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (ROOT_PREFIX_OPTION), conftext) conflval.option = ROOT_PREFIX_OPTION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 61: YY_RULE_SETUP #line 463 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (CONFIG_VERSION), conftext) conflval.option = CONFIG_VERSION; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 62: YY_RULE_SETUP #line 470 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (CONFIG_CHECK_WARN_UNRESTRICTED_RULES), conftext) conflval.option = CONFIG_CHECK_WARN_UNRESTRICTED_RULES; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 63: YY_RULE_SETUP #line 477 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, CONFIGOPTION (NUM_WORKERS), conftext) conflval.option = NUM_WORKERS; BEGIN (STRINGEQHUNT); return (CONFIGOPTION); } YY_BREAK case 64: YY_RULE_SETUP #line 484 "src/conf_lex.l" { log_msg(LOG_LEVEL_ERROR,"%s:%d: unknown config option: '%s' (line: '%s')", conf_filename, conf_linenumber, conftext, conf_linebuf); exit(INVALID_CONFIGURELINE_ERROR); } YY_BREAK case 65: YY_RULE_SETUP #line 489 "src/conf_lex.l" { /* group definition */ conflval.s=checked_strdup(conftext); LOG_LEX_TOKEN(lex_log_level, TGROUP, conftext) BEGIN(EXPREQUHUNT); return (TGROUP); } YY_BREAK case 66: YY_RULE_SETUP #line 496 "src/conf_lex.l" { /* group definition, deprecated group names */ 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); \ conflval.s=checked_strdup(conftext); LOG_LEX_TOKEN(lex_log_level, TGROUP, conftext) BEGIN(EXPREQUHUNT); return (TGROUP); } YY_BREAK case 67: YY_RULE_SETUP #line 504 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, '=', conftext) BEGIN(STRING); return('='); } YY_BREAK case 68: YY_RULE_SETUP #line 510 "src/conf_lex.l" { size_t length = strlen(conftext)-4; conflval.s=checked_malloc(length+1); strncpy(conflval.s, conftext+3, length); conflval.s[length] = '\0'; LOG_LEX_TOKEN(lex_log_level, TVARIABLE, conflval.s) return (TVARIABLE); } YY_BREAK case 69: YY_RULE_SETUP #line 519 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TSTRING, conftext) conflval.s=checked_strdup(conftext); return (TSTRING); } YY_BREAK case 70: YY_RULE_SETUP #line 525 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, (escaped) TSTRING, conftext) conflval.s=checked_strdup(conftext+1); return (TSTRING); } YY_BREAK case 71: YY_RULE_SETUP #line 531 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, (single-character) TSTRING, conftext) conflval.s=checked_strdup(conftext); return (TSTRING); } YY_BREAK case 72: YY_RULE_SETUP #line 537 "src/conf_lex.l" { LOG_LEX_TOKEN(lex_log_level, TSPACE, conftext) return (TSPACE); } YY_BREAK case 73: YY_RULE_SETUP #line 542 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext) BEGIN(CONFIG); } YY_BREAK case 74: YY_RULE_SETUP #line 547 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext) BEGIN(CONDITION); } YY_BREAK case 75: YY_RULE_SETUP #line 552 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext) BEGIN(EXPR); } YY_BREAK case 76: YY_RULE_SETUP #line 557 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, skip tab(s)/whitespace(s), conftext) BEGIN(STRING); } YY_BREAK case 77: YY_RULE_SETUP #line 562 "src/conf_lex.l" { LOG_LEX_TOKEN(LOG_LEVEL_DEBUG, found string -> unput, conftext) yyless(0); BEGIN(STRING); } YY_BREAK case 78: /* rule 78 can match eol */ YY_RULE_SETUP #line 568 "src/conf_lex.l" { log_msg(lex_log_level,"%s:%d: \u2534 TNEWLINE (text: '%s')", conf_filename, conf_linenumber, strlen(conftext) == 2?"\\r\\n":"\\n"); BEGIN 0; return (TNEWLINE); } YY_BREAK case YY_STATE_EOF(CONFIG): case YY_STATE_EOF(DEFSTMT): case YY_STATE_EOF(ENVVAR): case YY_STATE_EOF(EXPR): case YY_STATE_EOF(EXPREQUHUNT): case YY_STATE_EOF(PATH): case YY_STATE_EOF(STRING): case YY_STATE_EOF(STRINGS): case YY_STATE_EOF(STRINGEQHUNT): case YY_STATE_EOF(STRINGHUNT): case YY_STATE_EOF(CONDITION): case YY_STATE_EOF(CONDSTRING): #line 574 "src/conf_lex.l" { log_msg(lex_log_level,"%s:%d: \u2534 ", conf_filename, conf_linenumber); log_msg(LOG_LEVEL_NOTICE,"%s:%d: missing new line at end of file (line: '%s')", conf_filename, conf_linenumber, conf_linebuf); return (0); } YY_BREAK case 79: YY_RULE_SETUP #line 580 "src/conf_lex.l" { char *unexpected_character = conftext; switch (*conftext) { case '\r': unexpected_character = "\\r"; break; }; log_msg(LOG_LEVEL_ERROR,"%s:%d: unexpected character: '%s' (line: '%s')", conf_filename, conf_linenumber, unexpected_character, conf_linebuf); exit(INVALID_CONFIGURELINE_ERROR); } YY_BREAK case 80: YY_RULE_SETUP #line 589 "src/conf_lex.l" ECHO; YY_BREAK #line 2202 "src/conf_lex.c" case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of user's declarations */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc( (void *) b->yy_ch_buf, (yy_size_t) (b->yy_buf_size + 2) ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = NULL; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart( yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); /* "- 2" to take care of EOB's */ YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); } (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { yy_state_type yy_current_state; char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 494 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { int yy_is_jam; char *yy_cp = (yy_c_buf_p); YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 494 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; yy_is_jam = (yy_current_state == 493); return yy_is_jam ? 0 : yy_current_state; } #ifndef YY_NO_UNPUT #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart( yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer( yyin, YY_BUF_SIZE ); } yy_init_buffer( YY_CURRENT_BUFFER, input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer( b, file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree( (void *) b->yy_ch_buf ); yyfree( (void *) b ); } /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer( b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { yy_size_t num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ yy_size_t grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); if ( ! (yy_buffer_stack) ) YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return NULL; b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer( b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (const char * yystr ) { return yy_scan_bytes( yystr, (int) strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param yybytes the byte buffer to scan * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = (yy_size_t) (_yybytes_len + 2); buf = (char *) yyalloc( n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer( buf, n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yynoreturn yy_fatal_error (const char* msg ) { fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param _line_number line number * */ void yyset_lineno (int _line_number ) { yylineno = _line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param _in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * _in_str ) { yyin = _in_str ; } void yyset_out (FILE * _out_str ) { yyout = _out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int _bdebug ) { yy_flex_debug = _bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = NULL; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = NULL; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = NULL; yyout = NULL; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer( YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, const char * s2, int n ) { int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (const char * s ) { int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return malloc(size); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return realloc(ptr, size); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 589 "src/conf_lex.l" int confwrap(void){ return 1; } void conf_lex_string(const char * name, const char *string) { log_msg(LOG_LEVEL_DEBUG, "parse: '%s'", name); conf_linenumber = 0; conf_filename = checked_strdup(name); /* not to be freed, needed for logging */ progress_status(PROGRESS_CONFIG, conf_filename); conf_scan_string(string); } void conf_lex_file(const char * config) { log_msg(LOG_LEVEL_DEBUG, "parse: '%s'", config); conf_linenumber = 0; if (strcmp(config,"-") == 0) { conf_filename = checked_strdup("(stdin)"); /* not to be freed, needed for logging */ confin = stdin; } else { conf_filename = checked_strdup(config); /* not to be freed, needed for logging */ progress_status(PROGRESS_CONFIG, conf_filename); char *expanded_config = expand_tilde(checked_strdup(config)); confin = fopen( expanded_config, "r" ); if (!confin) { log_msg(LOG_LEVEL_ERROR,"cannot open config file '%s': %s", config, strerror(errno)); exit(IO_ERROR); } free(expanded_config); expanded_config=NULL; } conf_switch_to_buffer(conf_create_buffer( confin, YY_BUF_SIZE )); BEGIN 0; } void conf_lex_delete_buffer(void) { conf_delete_buffer( YY_CURRENT_BUFFER ); if (confin && confin != stdin) { if (fclose(confin)) { log_msg(LOG_LEVEL_WARNING, "fclose() failed for '%s': %s", conf_filename, strerror(errno)); } else { confin = NULL; } } } aide-0.19.3/src/symboltable.c0000644000175000017500000000254714412055402017205 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2002, 2005-2006,2022 Rami Lehti, Pablo Virolainen, * Richard van den Berg, Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include "list.h" #include "symboltable.h" list* list_find(char* s,list* item){ list* l; list* p; if (item==NULL) { return NULL; } p=item; while(p!=NULL){ if (strcmp(s,((symba*)p->data)->name)==0) return p; p=p->next; } l=item->prev; while(l!=NULL){ /* Insert bug to here return l-> return p */ if (strcmp(s,((symba*)l->data)->name)==0) return l; l=l->prev; } return NULL; } aide-0.19.3/src/conf_yacc.h0000644000175000017500000001173015137355020016617 0ustar00hvhaugwitzhvhaugwitz/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work under terms of your choice, so long as that work isn't itself a parser generator using the skeleton or a modified version thereof as a parser skeleton. Alternatively, if you modify or redistribute the parser skeleton itself, you may (at your option) remove this special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, especially those whose name start with YY_ or yy_. They are private implementation details that can be changed or removed. */ #ifndef YY_CONF_SRC_CONF_YACC_H_INCLUDED # define YY_CONF_SRC_CONF_YACC_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif #if YYDEBUG extern int confdebug; #endif /* "%code requires" blocks. */ #line 1 "src/conf_yacc.y" #include "conf_ast.h" #line 53 "src/conf_yacc.h" /* Token kinds. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE enum yytokentype { YYEMPTY = -2, YYEOF = 0, /* "end of file" */ YYerror = 256, /* error */ YYUNDEF = 257, /* "invalid token" */ TDEFINE = 258, /* "@@define" */ TUNDEFINE = 259, /* "@@undef" */ TIFDEF = 260, /* "@@ifdef" */ TIFNDEF = 261, /* "@@ifndef" */ TIFNHOST = 262, /* "@@ifnhost" */ TIFHOST = 263, /* "@@ifhost" */ TIF = 264, /* "@@if" */ TBOOLNOT = 265, /* "not" */ TBOOLFUNC = 266, /* "boolean function" */ TBOOLOP = 267, /* "boolean operator" */ TELSE = 268, /* "@@else" */ TENDIF = 269, /* "@@endif" */ TINCLUDE = 270, /* "@@include" */ TXINCLUDE = 271, /* "@@x_include" */ TSETENV = 272, /* "@@x_include_setenv" */ TGROUP = 273, /* "group name" */ TSTRING = 274, /* "string" */ TEXPR = 275, /* "group" */ TVARIABLE = 276, /* "variable name" */ TSPACE = 277, /* "whitespace" */ TNEWLINE = 278, /* "new line" */ TSELRXRULE = 279, /* "regular rule" */ TEQURXRULE = 280, /* "equals rule" */ TRECNEGRXRULE = 281, /* "recursive negative rule" */ TNONRECNEGRXRULE = 282, /* "non-recursive negative rule" */ CONFIGOPTION = 283 /* "configuration option" */ }; typedef enum yytokentype yytoken_kind_t; #endif /* Token kinds. */ #define YYEMPTY -2 #define YYEOF 0 #define YYerror 256 #define YYUNDEF 257 #define TDEFINE 258 #define TUNDEFINE 259 #define TIFDEF 260 #define TIFNDEF 261 #define TIFNHOST 262 #define TIFHOST 263 #define TIF 264 #define TBOOLNOT 265 #define TBOOLFUNC 266 #define TBOOLOP 267 #define TELSE 268 #define TENDIF 269 #define TINCLUDE 270 #define TXINCLUDE 271 #define TSETENV 272 #define TGROUP 273 #define TSTRING 274 #define TEXPR 275 #define TVARIABLE 276 #define TSPACE 277 #define TNEWLINE 278 #define TSELRXRULE 279 #define TEQURXRULE 280 #define TRECNEGRXRULE 281 #define TNONRECNEGRXRULE 282 #define CONFIGOPTION 283 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { #line 42 "src/conf_yacc.y" char* s; config_option option; bool_operator operator; ast* ast; if_condition* if_cond; bool_expression* bool_expr; attribute_expression* attr_expr; restriction_expression* rs_expr; ft_restriction_expression* ft_rs_expr; string_expression* string_expr; #line 146 "src/conf_yacc.h" }; typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 #endif extern YYSTYPE conflval; int confparse (ast** config_ast); #endif /* !YY_CONF_SRC_CONF_YACC_H_INCLUDED */ aide-0.19.3/src/commandconf.c0000644000175000017500000003443615041435703017163 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2006, 2010-2011, 2013, 2015-2016, 2019-2025 Rami Lehti, * Pablo Virolainen, Richard van den Berg, Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "aide.h" #include #include #include #include #include #include #include "attributes.h" #include "conf_ast.h" #include "config.h" #include "errorcodes.h" #include "hashsum.h" #include "list.h" #include "rx_rule.h" #include "url.h" #include "commandconf.h" #include "conf_lex.h" #include "log.h" #include "conf_yacc.h" #include "db.h" #include "db_config.h" #include "report.h" #include "symboltable.h" #include "md.h" #include "util.h" #include "conf_eval.h" #include "seltree.h" /*for locale support*/ #include "locale-aide.h" /*for locale support*/ #ifdef WITH_CURL #include "fopen.h" #endif #ifdef WITH_E2FSATTRS #include "e2fsattrs.h" #endif #include #include #include #define BUFSIZE 4096 #define ZBUFSIZE 16384 url_t* parse_url(char* val, int linenumber, char* filename, char* linebuf) { url_t* u=NULL; char* r=NULL; char* val_copy=NULL; int i=0; u=checked_malloc(sizeof(url_t)); /* We don't want to modify the original hence strdup(val) */ val_copy=checked_strdup(val); for(r=val_copy;r[0]!=':'&&r[0]!='\0';r++); if(r[0]!='\0'){ r[0]='\0'; r++; } u->type = get_url_type(val_copy); if (u->type) { switch (u->type) { case url_file : { if(r[0]=='/'&&(r+1)[0]=='/'&&(r+2)[0]=='/'){ u->value=checked_strdup(r+2); break; } if(r[0]=='/'&&(r+1)[0]=='/'&&(r+2)[0]!='/'){ char* t=r+2; r+=2; for(i=0;r[0]!='/'&&r[0]!='\0';r++,i++); if(r[0]=='\0'){ LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "invalid file-URL '%s': no path after hostname", val) free(val_copy); free(u); return NULL; } if( (strcmp(t,"localhost") != 0) && !( conf->hostname && strcmp(t,conf->hostname)==0)){ LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "invalid file-URL '%s': cannot use hostname other than 'localhost' or '%s'", val, conf->hostname); free(u); free(val_copy); return NULL; } u->value=checked_strdup(r); r[0]='\0'; break; } u->value=checked_strdup(r); break; } case url_ftp : case url_https : case url_http : { #ifdef WITH_CURL u->value=checked_strdup(val); #else LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "%s", "http, https and ftp URL support not compiled in, recompile AIDE with '--with-curl'") free(val_copy); free(u); return NULL; #endif /* WITH CURL */ break; } case url_fd: case url_stdin: case url_stdout: case url_stderr: { u->value=checked_strdup(r); break; } case url_syslog : { #ifdef HAVE_SYSLOG u->value=checked_strdup(r); #else LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "%s", "syslog url support not compiled in, recompile AIDE with syslog support") free(val_copy); free(u); return NULL; #endif break; } } } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "unknown URL-type: '%s'", val_copy); free(val_copy); free(u); return NULL; } free(val_copy); u->raw = checked_strdup(val); return u; } int parse_config(char *before, char *config, char* after) { if(before==NULL && after==NULL && (config==NULL||strcmp(config,"")==0)){ log_msg(LOG_LEVEL_ERROR,_("missing configuration (use '--config' '--before' or '--after' command line parameter)")); return RETFAIL; } ast* config_ast = NULL; if (before) { conf_lex_string("(--before)", before); if(confparse(&config_ast)){ return RETFAIL; } conf_lex_delete_buffer(); eval_config(config_ast, 0, NULL); deep_free(config_ast); config_ast = NULL; } if (config) { conf_lex_file(config); if(confparse(&config_ast)){ return RETFAIL; } conf_lex_delete_buffer(); eval_config(config_ast, 0, NULL); deep_free(config_ast); config_ast = NULL; } if (after) { conf_lex_string("(--after)", after); if(confparse(&config_ast)){ return RETFAIL; } conf_lex_delete_buffer(); eval_config(config_ast, 0, NULL); deep_free(config_ast); config_ast = NULL; } return RETOK; } int conf_input_wrapper(char* buf, int max_size, FILE* in) { int retval=0; retval=fread(buf,1,max_size,in); return retval; } void do_define(char* name, char* value, int linenumber, char* filename, char* linebuf) { symba* s=NULL; list* l=NULL; if(!(l=list_find(name,conf->defsyms))){ LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_CONFIG, "define '%s' with value '%s'", name, value) s=(symba*)checked_malloc(sizeof(symba)); s->name=checked_strdup(name); s->value=value; conf->defsyms=list_append(conf->defsyms,(void*)s); } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_NOTICE, "redefine '%s' with value '%s' (previous value: '%s')", name, value, ((symba*)l->data)->value) free(((symba*)l->data)->value); ((symba*)l->data)->value=NULL; ((symba*)l->data)->value=value; } } void do_undefine(char* name, int linenumber, char* filename, char* linebuf) { list*r=NULL; if((r=list_find(name,conf->defsyms))){ LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_CONFIG, "undefine '%s' (value: '%s')", name, ((symba*)r->data)->value) free(((symba*)r->data)->name); free(((symba*)r->data)->value); free((symba*)r->data); r->data=NULL; conf->defsyms=list_delete_item(r); } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_NOTICE, "variable '%s' to be undefined not found", name); } } bool add_rx_rule_to_tree(char* rx, char* rule_prefix, rx_restriction_t restriction, DB_ATTR_TYPE attr, int type, seltree *tree, int linenumber, char* filename, char* linebuf) { rx_rule* r=NULL; bool retval = false; char *attr_str = NULL; char *rs_str = NULL; char *regex; char *node_path = NULL; if (rule_prefix) { int length = strlen(rule_prefix)+strlen(rx); regex = checked_malloc(length+1); strncpy(regex, rule_prefix, length+1); strncat(regex, rx, length-strlen(rule_prefix)+1); log_msg(LOG_LEVEL_DEBUG, "prepend regex '%s' with prefix '%s': '%s'", rx, rule_prefix, regex); } else { regex = checked_strdup(rx); } if ((r = add_rx_to_tree(regex, restriction, type, tree, linenumber, filename, linebuf, &node_path)) == NULL) { retval = false; }else { r->prefix = rule_prefix; attr &= validate_hashes(attr, linenumber, filename, linebuf); DB_ATTR_TYPE unsupported_attrs = attr& (0 #ifndef WITH_ACL |ATTR(attr_acl) #endif #ifndef WITH_SELINUX |ATTR(attr_selinux) #endif #ifndef WITH_XATTR |ATTR(attr_xattrs) #endif #ifndef WITH_E2FSATTRS |ATTR(attr_e2fsattrs) #endif #ifndef WITH_CAPABILITIES |ATTR(attr_capabilities) #endif #ifndef HAVE_FSTYPE |ATTR(attr_fs_type) #endif ) ; if (unsupported_attrs) { char *str; LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_WARNING, "ignoring not compiiled-in attribute(s): %s", str = diff_attributes(0, unsupported_attrs)); free(str); attr &= ~unsupported_attrs; } r->attr=attr; if (attr&ATTR(attr_sizeg)) { log_msg(LOG_LEVEL_WARNING, "%s:%d: Using 'S' attribute is DEPRECATED and will be removed in the release after next. Update your config and use 'growing+s' instead (line: '%s')", filename, linenumber, linebuf); } if (attr&ATTR(attr_compressed) && !(attr&get_hashes(false))) { log_msg(LOG_LEVEL_WARNING, "%s:%d: ignore 'comprressed' attribute (no hashsum attributes are set) (line: '%s')", filename, linenumber, linebuf); } conf->db_out_attrs |= attr; LOG_CONFIG_FORMAT_LINE_PREFIX(LOG_LEVEL_CONFIG, "add %s '%s%s %s %s' to node '%s'", get_rule_type_long_string(type), get_rule_type_char(type), r->rx, rs_str = get_restriction_string(r->restriction), attr_str = diff_attributes(0, r->attr), node_path) free(rs_str); free(attr_str); retval = true; } return retval; } DB_ATTR_TYPE do_groupdef(char* group,DB_ATTR_TYPE value) { log_msg(LOG_LEVEL_DEBUG, "define attribute group '%s' with value %llu", group, value); list* r=NULL; symba* s=NULL; if((r=list_find(group,conf->groupsyms))){ DB_ATTR_TYPE prev_value = ((symba*)r->data)->ival; ((symba*)r->data)->ival=value; return prev_value; } /* This is a new group */ s=checked_malloc(sizeof(symba)); s->name=checked_strdup(group); s->ival=value; conf->groupsyms=list_append(conf->groupsyms,(void*)s); return 0; } DB_ATTR_TYPE get_groupval(char* group) { list* r=NULL; if((r=list_find(group,conf->groupsyms))){ return (((symba*)r->data)->ival); } return DB_ATTR_UNDEF; } bool do_dbdef(DB_TYPE dbtype ,char* val, int linenumber, char* filename, char* linebuf) { url_t* u=NULL; database *db = NULL; char *db_option_name = NULL; switch(dbtype) { case DB_TYPE_IN: { db_option_name = "database_in"; db = &(conf->database_in); break; } case DB_TYPE_OUT: { db_option_name = "database_out"; db = &(conf->database_out); break; } case DB_TYPE_NEW: { db_option_name = "database_new"; db = &(conf->database_new); break; } } if(db->url == NULL){ if ((u=parse_url(val, linenumber, filename, linebuf)) != NULL) { /* FIXME Check the URL if you add support for databases that cannot be * both input and output urls */ switch (dbtype) { case DB_TYPE_IN: case DB_TYPE_NEW:{ switch (u->type) { case url_stdout: case url_stderr: case url_syslog: { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "'%s': unsupported URL-type: '%s'", db_option_name, get_url_type_string(u->type)) return false; } case url_stdin: case url_ftp: case url_http: case url_https: case url_fd: case url_file: /* url type is supported */ break; } break; } case DB_TYPE_OUT: { switch (u->type) { case url_stdin: case url_stderr: case url_syslog: { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "'%s': unsupported URL-type: '%s'", db_option_name, get_url_type_string(u->type)) return false; } case url_stdout: case url_ftp: case url_http: case url_https: case url_fd: case url_file: /* url type is supported */ break; } break; } } db->url = u; db->linenumber = linenumber; db->filename = filename; db->linebuf = linebuf?checked_strdup(linebuf):NULL; LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_CONFIG, "set '%s' option to '%s'", db_option_name, u->raw) } else { return false; } } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_NOTICE, "'%s' option already set to '%s' (ignore new value '%s')", db_option_name, (db->url)->raw, val); } return true; } bool do_repurldef(char* val, int linenumber, char* filename, char* linebuf) { url_t* u = parse_url(val, linenumber, filename, linebuf); return add_report_url(u, linenumber, filename, linebuf); } bool do_reportlevel(char* val, int linenumber, char* filename, char* linebuf) { REPORT_LEVEL report_level = REPORT_LEVEL_UNKNOWN; report_level = get_report_level(val); if (report_level) { conf->report_level = report_level; LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_CONFIG, "set 'report_level' option to '%s' (raw: %d)", val, report_level) return true; } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "invalid report level: '%s'", val); return false; } } bool do_rootprefix(char* val, int linenumber, char* filename, char* linebuf) { if (conf->root_prefix == NULL) { conf->root_prefix=val; conf->root_prefix_length=strlen(conf->root_prefix); if (conf->root_prefix_length && conf->root_prefix[conf->root_prefix_length-1] == '/') { conf->root_prefix[--conf->root_prefix_length] = '\0'; LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_NOTICE, "removed trailing '/' from root prefix: '%s'", conf->root_prefix); } LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_CONFIG, "set 'root_prefix' option to '%s'", conf->root_prefix) return true; } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_NOTICE, "'root_prefix' option already set to '%s' (ignore new value '%s')", conf->root_prefix, val); return false; } } long do_num_workers(const char *str) { char *err; long number = strtol(str,&err,10); if (err[0] == '%' && err[1] == '\0') { if (number >= 0 && number <= 100) { long num_of_processors = sysconf(_SC_NPROCESSORS_ONLN); return ceill(num_of_processors * number / 100.0); } else { return -1; } } else if(*err != '\0' || number < 0 || errno == ERANGE) { return -1; } return number; } #ifdef WITH_E2FSATTRS void do_report_ignore_e2fsattrs(char* val, int linenumber, char* filename, char* linebuf) { conf->report_ignore_e2fsattrs = 0UL; if (strcmp(val, "0") != 0) { while (*val) { unsigned long flag = e2fsattrs_get_flag(*val); if (flag) { conf->report_ignore_e2fsattrs |= flag; } else { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_NOTICE, "ignore invalid ext2 file attribute: '%c'", *val) } val++; } } } #endif aide-0.19.3/src/file.c0000644000175000017500000001422015032264625015606 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2016,2020,2021,2024,2025 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "file.h" #ifdef HAVE_FSTYPE #include #include #include #ifndef EXFAT_SUPER_MAGIC #define EXFAT_SUPER_MAGIC 0x2011BAB0 #endif #ifndef FUSE_SUPER_MAGIC #define FUSE_SUPER_MAGIC 0x65735546 #endif #ifndef XFS_SUPER_MAGIC #define XFS_SUPER_MAGIC 0x58465342 #endif #include #include #include "util.h" #endif #include #ifdef HAVE_FSTYPE filesystem_t filesystems[] = { { "9p", V9FS_MAGIC }, { "autofs", AUTOFS_SUPER_MAGIC }, { "bcachefs", 0xca451a4e }, { "binfmt", BINFMTFS_MAGIC }, { "bpf", BPF_FS_MAGIC }, { "btrfs", BTRFS_SUPER_MAGIC }, { "cgroup", CGROUP_SUPER_MAGIC }, { "cgroup2", CGROUP2_SUPER_MAGIC }, { "configfs", 0x62656570 }, { "debugfs", DEBUGFS_MAGIC }, { "devpts", DEVPTS_SUPER_MAGIC }, { "efivarfs", EFIVARFS_MAGIC }, { "exfat", EXFAT_SUPER_MAGIC }, { "ext", EXT2_SUPER_MAGIC }, /* ext2/ext3/ext4 */ { "f2fs", F2FS_SUPER_MAGIC }, { "fuse", FUSE_SUPER_MAGIC }, { "fusectl", 0x65735543 }, { "hugetlbfs", HUGETLBFS_MAGIC }, { "mqueue", 0x19800202 }, { "nfs", NFS_SUPER_MAGIC }, { "nilfs", NILFS_SUPER_MAGIC }, { "overlayfs", OVERLAYFS_SUPER_MAGIC }, { "proc", PROC_SUPER_MAGIC }, { "pstore", PSTOREFS_MAGIC }, { "ramfs", RAMFS_MAGIC }, { "securityfs", SECURITYFS_MAGIC }, { "selinuxfs", SELINUX_MAGIC }, { "squashfs", SQUASHFS_MAGIC }, { "sysfs", SYSFS_MAGIC }, { "tmpfs", TMPFS_MAGIC }, { "tracefs", TRACEFS_MAGIC }, { "udf", UDF_SUPER_MAGIC }, { "vfat", MSDOS_SUPER_MAGIC }, { "xfs", XFS_SUPER_MAGIC }, }; int num_filesystems = sizeof(filesystems)/sizeof(filesystem_t); #endif typedef struct { char c; char *s; FT_TYPE r; mode_t ft; } f_type_t; static f_type_t filetypes[] = { { 'f', "regular file", FT_REG, S_IFREG }, { 'd', "directory", FT_DIR, S_IFDIR }, #ifdef S_IFIFO { 'p', "FIFO", FT_FIFO, S_IFIFO }, #endif { 'l', "symbolic link", FT_LNK, S_IFLNK }, { 'b', "block device", FT_BLK, S_IFBLK }, { 'c', "character device", FT_CHR, S_IFCHR }, #ifdef S_IFSOCK { 's', "socket", FT_SOCK, S_IFSOCK }, #endif #ifdef S_IFDOOR { 'D', "door", FT_DOOR, S_IFDOOR }, #endif #ifdef S_IFPORT { 'P', "port", FT_PORT, S_IFPORT }, #endif }; static int num_filetypes = sizeof(filetypes)/sizeof(f_type_t); char get_f_type_char_from_f_type(FT_TYPE r) { for (int i = 0 ; i < num_filetypes; ++i) { if (r == filetypes[i].r) { return filetypes[i].c; } } return '?'; } char *get_f_type_string_from_f_type(FT_TYPE r) { for (int i = 0 ; i < num_filetypes; ++i) { if (r == filetypes[i].r) { return filetypes[i].s; } } return "unknown file type"; } char get_f_type_char_from_perm(mode_t mode) { mode_t ft = mode & S_IFMT; for (int i = 0 ; i < num_filetypes; ++i) { if (ft == filetypes[i].ft) { return filetypes[i].c; } } return '?'; } char *get_f_type_string_from_perm(mode_t mode) { mode_t ft = mode & S_IFMT; for (int i = 0 ; i < num_filetypes; ++i) { if (ft == filetypes[i].ft) { return filetypes[i].s; } } return "unknown file type"; } FT_TYPE get_f_type_from_char(char c) { for (int i = 0 ; i < num_filetypes; ++i) { if (c == filetypes[i].c) { return filetypes[i].r; } } return FT_NULL; } FT_TYPE get_f_type_from_perm(mode_t mode) { mode_t ft = mode & S_IFMT; for (int i = 0 ; i < num_filetypes; ++i) { if (ft == filetypes[i].ft) { return filetypes[i].r; } } return FT_NULL; } #ifdef HAVE_FSTYPE FS_TYPE get_fs_type_from_string(const char *fs_type_str) { for (int i = 0 ; i < num_filesystems; ++i) { if (strcmp(filesystems[i].str, fs_type_str) == 0) { return filesystems[i].magic; } } if (strncmp(fs_type_str, "0x", 2) == 0) { long long ll; char* e; ll = strtoll(fs_type_str, &e, 16); if (*e =='\0' && ll > 0 && ll <= UINT_MAX) { return (FS_TYPE) ll; } } return 0; } int generate_fs_type_string(FS_TYPE magic, char* str) { for (int i = 0 ; i < num_filesystems; ++i) { if (filesystems[i].magic == magic) { size_t length = strlen(filesystems[i].str)+1; if (str) { sprintf(str, "%s", filesystems[i].str); } return length; } } size_t length = snprintf(NULL, 0, "0x%lx", magic)+1; if (str) { sprintf(str, "0x%lx", magic); } return length; } char *get_fs_type_string_from_magic(FS_TYPE magic) { char *str = NULL; int n = generate_fs_type_string(magic, str); str = checked_malloc(n); generate_fs_type_string(magic, str);; return str; } #endif aide-0.19.3/src/be.c0000644000175000017500000001311314774422002015252 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2003, 2005-2006, 2010-2011, 2013, 2019-2023 Rami Lehti, * Pablo Virolainen, Richard van den Berg, Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #ifdef HAVE_FCNTL #include #endif #include #include #ifdef WITH_ZLIB #include #endif #include "log.h" #include "util.h" #include "errorcodes.h" #ifdef WITH_CURL #include "fopen.h" #endif #include "be.h" #include "url.h" /*for locale support*/ #include "locale-aide.h" /*for locale support*/ void* be_init(url_t* u, bool readonly, bool iszipped, bool append, int linenumber, char* filename, char* linebuf, bool *created) { FILE* fh=NULL; long a=0; char* err=NULL; int fd; #if HAVE_FCNTL && HAVE_FTRUNCATE struct flock fl; #endif switch (u->type) { case url_file : { u->value = expand_tilde(u->value); log_msg(LOG_LEVEL_DEBUG, "open (%s, gzip: %s, append: %s) file '%s'", readonly?"read-only":"read/write", btoa(iszipped), btoa(append), u->value); bool new_file = false; if (readonly) { fd = open(u->value, O_RDONLY, 0); } else { int flag_truncate; #if HAVE_FCNTL && HAVE_FTRUNCATE flag_truncate = 0; #else flag_truncate = O_TRUNC; #endif fd = open(u->value, O_CREAT|O_EXCL|O_RDWR, 0666); new_file = fd >= 0; if (fd == -1 && errno == EEXIST) { fd = open(u->value, O_RDWR|(append?O_APPEND:flag_truncate), 0666); } } if(fd==-1) { LOG_CONFIG_FORMAT_LINE(LOG_LEVEL_ERROR, "open (%s) failed for file '%s': %s", readonly?"read-only":"read/write", u->value, strerror(errno)); return NULL; } else { if (created) { *created = new_file; } log_msg(LOG_LEVEL_DEBUG, "%s file '%s' with fd=%i",new_file?"created":"opened existing", u->value,fd); } #if HAVE_FCNTL && HAVE_FTRUNCATE if(!readonly) { if (strcmp(u->value, "/dev/null")) { fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; log_msg(LOG_LEVEL_DEBUG, "try to get lock for file '%s'", u->value); if (fcntl(fd, F_SETLK, &fl) == -1) { log_msg(LOG_LEVEL_ERROR, "cannot get lock for file '%s': %s", u->value, strerror(errno)); exit(LOCK_ERROR); } else { log_msg(LOG_LEVEL_DEBUG, "successfully got lock for file '%s'", u->value); } if (!append) { if(ftruncate(fd,0)==-1) { log_msg(LOG_LEVEL_ERROR,_("ftruncate failed for file %s: %s"),u->value, strerror(errno)); return NULL; } else { log_msg(LOG_LEVEL_DEBUG, "successfully truncated file '%s' to size 0", u->value); } } } else { log_msg(LOG_LEVEL_DEBUG, "skip lock for '/dev/null'"); } } #endif #ifdef WITH_ZLIB if(iszipped && !readonly){ gzFile gzfh = gzdopen(fd,"wb9"); if(gzfh==NULL){ log_msg(LOG_LEVEL_ERROR, _("gzdopen (%s) failed for file %s"), readonly?"read-only":"read/write", u->value); } return gzfh; } else{ #endif fh=fdopen(fd,readonly?"r":"w+"); if(fh==NULL){ log_msg(LOG_LEVEL_ERROR, _("fdopen (%s) failed for file '%s': %s"), readonly?"read-only":"read/write", u->value, strerror(errno)); } return fh; #ifdef WITH_ZLIB } #endif } case url_stdout : { #ifdef WITH_ZLIB if(iszipped){ return gzdopen(fileno(stdout),"wb"); } else{ #endif return stdout; #ifdef WITH_ZLIB } #endif } case url_stdin : { #ifdef WITH_ZLIB if(iszipped){ return gzdopen(fileno(stdin),"r"); } else{ #endif return stdin; #ifdef WITH_ZLIB } #endif } case url_stderr : { #ifdef WITH_ZLIB if(iszipped){ return gzdopen(fileno(stderr),"wb"); } else{ #endif return stderr; #ifdef WITH_ZLIB } #endif } case url_fd : { a=strtol(u->value,&err,10); if(*err!='\0'||errno==ERANGE){ log_msg(LOG_LEVEL_ERROR,"illegal file descriptor value:%s",u->value); } #ifdef WITH_ZLIB if(iszipped && !readonly){ gzFile gzfh = gzdopen(a,"w"); if(gzfh==NULL){ log_msg(LOG_LEVEL_ERROR,"couldn't reopen file descriptor %li",a); } return gzfh; } else{ #endif fh=fdopen(a,readonly?"r":"w"); if(fh==NULL){ log_msg(LOG_LEVEL_ERROR,"couldn't reopen file descriptor %li",a); } return fh; #ifdef WITH_ZLIB } #endif } #ifdef WITH_CURL case url_http: case url_https: case url_ftp: { log_msg(LOG_LEVEL_DEBUG,_("opening curl '%s' for %s"),u->value,readonly?"r":"w+"); if (iszipped) { return NULL; } return url_fopen(u->value,readonly?"r":"w+"); } #endif /* WITH CURL */ default:{ log_msg(LOG_LEVEL_ERROR, "unsupported backend: %i", u->type); return NULL; } } /* Not reached */ return NULL; } aide-0.19.3/src/attributes.c0000644000175000017500000001571214774422002017061 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2015,2016,2019-2025 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include #include #include "util.h" #include "attributes.h" attributes_t attributes[] = { { ATTR(attr_filename), NULL, NULL, "name", "name", '\0' }, { ATTR(attr_linkname), "l", "Lname", "lname", "link_name", 'l' }, { ATTR(attr_perm), "p", "Perm", "perm", "perm", 'p' }, { ATTR(attr_uid), "u", "Uid", "uid", "uid", 'u' }, { ATTR(attr_gid), "g", "Gid", "gid", "gid", 'g' }, { ATTR(attr_size), "s", "Size", "size", "size", '>' }, { ATTR(attr_atime), "a", "Atime", "atime", "access_time", 'a' }, { ATTR(attr_ctime), "c", "Ctime", "ctime", "change_time", 'c' }, { ATTR(attr_mtime), "m", "Mtime" , "mtime", "modify_time", 'm' }, { ATTR(attr_inode), "i", "Inode", "inode", "inode", 'i' }, { ATTR(attr_bcount), "b", "Bcount", "bcount", "block_count", 'b' }, { ATTR(attr_linkcount), "n", "Linkcount", "lcount", "link_count", 'n' }, { ATTR(attr_md5), "md5", "MD5", "md5", "md5", '\0' }, { ATTR(attr_sha1), "sha1", "SHA1", "sha1", "sha1", '\0' }, { ATTR(attr_rmd160), "rmd160", "RMD160", "rmd160", "rmd160", '\0' }, { ATTR(attr_tiger), "tiger", "TIGER", "tiger", "tiger", '\0' }, { ATTR(attr_crc32), "crc32", "CRC32", "crc32", "crc32", '\0' }, { ATTR(attr_haval), "haval", "HAVAL", "haval", "haval", '\0' }, { ATTR(attr_gostr3411_94), "gost", "GOST", "gost", "gost", '\0' }, { ATTR(attr_crc32b), "crc32b", "CRC32B", "crc32b", "crc32b", '\0' }, { ATTR(attr_attr), NULL, "Attributes", "attr", "attributes", '\0' }, { ATTR(attr_acl), "acl", "ACL", "acl", "acl", 'A' }, { ATTR(attr_bsize), NULL, NULL, NULL, NULL, '\0' }, { ATTR(attr_rdev), NULL, NULL , NULL, NULL, '\0' }, { ATTR(attr_dev), NULL, NULL , NULL, NULL, '\0' }, { ATTR(attr_allhashsums), NULL, NULL, NULL, NULL, 'H' }, /* "H" is also default compound group for all compiled in hashsums */ { ATTR(attr_sizeg), "S", "Size (>)", NULL, "growing_size", '\0' }, { ATTR(attr_checkinode), "I", NULL, NULL, NULL, '\0' }, { ATTR(attr_allownewfile), "ANF", NULL, NULL, NULL, '\0' }, { ATTR(attr_allowrmfile), "ARF", NULL, NULL, NULL, '\0' }, { ATTR(attr_sha256), "sha256", "SHA256", "sha256", "sha256", '\0' }, { ATTR(attr_sha512), "sha512", "SHA512", "sha512", "sha512", '\0' }, { ATTR(attr_selinux), "selinux", "SELinux", "selinux", "selinux", 'S' }, { ATTR(attr_xattrs), "xattrs", "XAttrs", "xattrs", "xattrs", 'X' }, { ATTR(attr_whirlpool), "whirlpool", "WHIRLPOOL", "whirlpool", "whirlpool", '\0' }, { ATTR(attr_ftype), "ftype", "File type", NULL, "file_type", '!' }, { ATTR(attr_e2fsattrs), "e2fsattrs", "E2FSAttrs", "e2fsattrs", "e2fsattrs", 'E' }, { ATTR(attr_capabilities), "caps", "Caps", "capabilities", "capabilities", 'C' }, { ATTR(attr_stribog256), "stribog256", "STRIBOG256", "stribog256", "stribog256", '\0' }, { ATTR(attr_stribog512), "stribog512", "STRIBOG512", "stribog512", "stribog512", '\0' }, { ATTR(attr_growing), "growing", NULL, NULL, NULL, '\0' }, { ATTR(attr_compressed), "compressed", NULL, NULL, NULL, '\0' }, { ATTR(attr_sha512_256), "sha512_256", "SHA512/256", "sha512_256", "sha512-256", '\0' }, { ATTR(attr_sha3_256), "sha3_256", "SHA3-256", "sha3_256", "sha3-256", '\0' }, { ATTR(attr_sha3_512), "sha3_512", "SHA3-512", "sha3_512", "sha3-512", '\0' }, { ATTR(attr_fs_type), "fstype", "FS type", "fstype", "fs_type", 'F' }, }; DB_ATTR_TYPE num_attrs = sizeof(attributes)/sizeof(attributes_t); static int get_diff_attrs_string(DB_ATTR_TYPE a, DB_ATTR_TYPE b, char *str, bool db) { int n = 0; for (ATTRIBUTE i = 0; i < num_attrs; ++i) { if (db?attributes[i].db_name:attributes[i].config_name) { if (((1LLU< #include #include "conf_ast.h" #include "conf_lex.h" #include "log.h" #include "rx_rule.h" #include "util.h" LOG_LEVEL ast_log_level = LOG_LEVEL_TRACE; config_option_t config_options[] = { { ACL_NO_SYMLINK_FOLLOW_OPTION, "acl_no_symlink_follow", NULL }, { DATABASE_ADD_METADATA_OPTION, NULL, NULL }, { DATABASE_ATTRIBUTES_OPTION, NULL, NULL }, { DATABASE_GZIP_OPTION, NULL, NULL }, { DATABASE_IN_OPTION, NULL, NULL }, { DATABASE_OUT_OPTION, NULL, NULL }, { DATABASE_NEW_OPTION, NULL, NULL }, { LOG_LEVEL_OPTION, NULL, NULL }, { REPORT_BASE16_OPTION, NULL, NULL }, { REPORT_DETAILED_INIT_OPTION, NULL, NULL }, { REPORT_FORCE_ATTRS_OPTION, "report_force_attrs", "Forced attributes" }, { REPORT_GROUPED_OPTION, NULL, NULL }, { REPORT_IGNORE_ADDED_ATTRS_OPTION, "report_ignore_added_attrs", "Ignored added attributes" }, { REPORT_IGNORE_REMOVED_ATTRS_OPTION, "report_ignore_removed_attrs", "Ignored removed attributes" }, { REPORT_IGNORE_CHANGED_ATTRS_OPTION, "report_ignore_changed_attrs", "Ignored changed attributes" }, { REPORT_IGNORE_E2FSATTRS_OPTION, "report_ignore_e2fsattrs", "Ignored e2fs attributes" }, { REPORT_LEVEL_OPTION, "report_level", "Report level" }, { REPORT_QUIET_OPTION, NULL, NULL }, { REPORT_APPEND_OPTION, NULL, NULL }, { REPORT_SUMMARIZE_CHANGES_OPTION, NULL, NULL }, { REPORT_URL_OPTION, NULL, NULL }, { ROOT_PREFIX_OPTION, "root_prefix", "Root prefix" }, { WARN_DEAD_SYMLINKS_OPTION, NULL, NULL }, { CONFIG_VERSION, "config_version", "Config version used" }, { CONFIG_CHECK_WARN_UNRESTRICTED_RULES, NULL, NULL }, { REPORT_FORMAT_OPTION, NULL, NULL }, { LIMIT_CMDLINE_OPTION, "limit", "Limit" }, { NUM_WORKERS, NULL, NULL }, }; static ast* new_ast_node(void) { ast* a = checked_malloc(sizeof(ast)); a->linenumber = conf_linenumber; a->filename = conf_filename; a->linebuf = conf_linebuf; a->next = NULL; return a; } ast* new_string_option_statement(config_option option, string_expression* value) { ast* a = new_ast_node(); a->type = config_option_type; a->statement._config.option = option; a->statement._config.a = NULL; a->statement._config.e = value; log_msg(ast_log_level, "ast: new string option statement (%p): option: %d, value: %p", (void*) a, option, (void*) value); return a; } ast* new_attribute_option_statement(config_option option, attribute_expression* value) { ast* a = new_ast_node(); a->type = config_option_type; a->statement._config.option = option; a->statement._config.a = value; a->statement._config.e = NULL; log_msg(ast_log_level, "ast: new attribute option statement (%p): option: %d, value: %p", (void*) a, option, (void*) value); return a; } ast* new_include_statement(string_expression* path, string_expression* rx, bool execute, string_expression* prefix) { ast* a = new_ast_node(); a->type = include_statement_type; a->statement._include.path = path; a->statement._include.rx = rx; a->statement._include.execute = execute; a->statement._include.prefix = prefix; log_msg(ast_log_level, "ast: new include statement (%p): path: %p, rx: %p, execute: %s, prefix: %p", (void*) a, (void*) path, (void*) rx, btoa(execute), (void*) prefix); return a; } ast* new_x_include_setenv_statement(char *variable, string_expression *value) { ast* a = new_ast_node(); a->type = x_include_setenv_statement_type; a->statement._x_include_setenv.variable = variable; a->statement._x_include_setenv.value = value; log_msg(ast_log_level, "ast: new x_include_setenv statement (%p): variable: '%s', value: %p", (void*) a, variable, (void*) value); return a; } ast* new_define_statement(char *name, string_expression *value) { ast* a = new_ast_node(); a->type = define_statement_type; a->statement._define.name = name; a->statement._define.value = value; log_msg(ast_log_level, "ast: new define statement (%p): name: '%s', value: %p", (void*) a, name, (void*) value); return a; } ast* new_undefine_statement(char *name) { ast* a = new_ast_node(); a->type = undefine_statement_type; a->statement._undefine.name = name; log_msg(ast_log_level, "ast: new undefine statement (%p): name: '%s'", (void*) a, name); return a; } ast* new_group_statement(char* name, attribute_expression* expr) { ast* a = new_ast_node(); a->type = group_statement_type; a->statement._group.name = name; a->statement._group.expr = expr; log_msg(ast_log_level, "ast: new group statement (%p): name: '%s', expr: %p", (void*) a, name, (void*) expr); return a; } bool_expression* new_string_bool_expression(bool_operator op, string_expression* left, string_expression* right) { bool_expression* e = checked_malloc(sizeof(bool_expression)); e->op = op; e->left._str = left; e->right._str = right; log_msg(ast_log_level, "ast: new string bool expression (%p): op: %d, left: %p, right: %p", (void*) e, op, (void*) left, (void*) right); return e; } bool_expression* new_bool_expression(bool_operator op, bool_expression* left, bool_expression* right) { bool_expression* e = checked_malloc(sizeof(bool_expression)); e->op = op; e->left._bool = left; e->right._bool = right; log_msg(ast_log_level, "ast: new bool expression (%p): op: %d, left: %p, right: %p", (void*) e, op, (void*) left, (void*) right); return e; } if_condition* new_if_condition(bool_expression* expression) { if_condition* c = checked_malloc(sizeof(if_condition)); c->linenumber = conf_linenumber; c->filename = conf_filename; c->linebuf = conf_linebuf; c->expression = expression; log_msg(ast_log_level, "ast: if condition (%p): expression: %p", (void*) c, (void*) expression); return c; } attribute_expression* new_attribute_expression(attribute_operator op, attribute_expression* left, char* right) { attribute_expression* e = checked_malloc(sizeof(attribute_expression)); e->op = op; e->left = left; e->right = right; log_msg(ast_log_level, "ast: new attribute expression (%p): op: %d, left: %p, right: '%s'", (void*) e, op, (void*) left, right); return e; } ft_restriction_expression* new_ft_restriction_expression(ft_restriction_expression* left, char* right) { ft_restriction_expression* e = checked_malloc(sizeof(ft_restriction_expression)); e->right = right; e->left = left; log_msg(ast_log_level, "ast: new file type restriction expression (%p): left: %p, right: '%s'", (void*) e, (void*) left, right); return e; } restriction_expression* new_restriction_expression(ft_restriction_expression* f_types, char* fs_type) { restriction_expression* e = checked_malloc(sizeof(restriction_expression)); e->f_types = f_types; e->fs_type = fs_type; log_msg(ast_log_level, "ast: new restriction expression (%p): f_types: '%p', fs_type: %s", (void*) e, (void*) f_types, (fs_type != NULL) ? fs_type : "(null)"); return e; } ast* new_if_statement(struct if_condition* condition, struct ast* if_branch, struct ast* else_branch) { ast* e = new_ast_node(); e->type = if_statement_type; e->statement._if.condition = condition; e->statement._if.if_branch = if_branch; e->statement._if.else_branch = else_branch; log_msg(ast_log_level, "ast: new if statement (%p): condition: %p, if_branch: %p, else_branch: %p", (void*) e, (void*) condition, (void*) if_branch, (void*) else_branch); return e; } ast* new_rule_statement(AIDE_RULE_TYPE rule_type, string_expression* path, restriction_expression* restriction, attribute_expression* attrs) { ast* e = new_ast_node(); e->type = rule_statement_type; e->statement._rule.type = rule_type; e->statement._rule.path = path; e->statement._rule.restriction = restriction; e->statement._rule.attributes = attrs; log_msg(ast_log_level, "ast: new rule statement (%p): type: %s, path: %p, restriction: %p, attributes: %p", (void*) e, get_rule_type_long_string(rule_type), (void*) path, (void*) restriction, (void*) attrs); return e; } string_expression* new_string(char *str) { string_expression* e = checked_malloc(sizeof(string_expression)); e->op = STR_OP_STR; e->str = str; e->left = NULL; e->right = NULL; log_msg(ast_log_level, "ast: new string (%p): str: '%s'", (void*) e, str); return e; } string_expression* new_variable(char *name) { string_expression* e = checked_malloc(sizeof(string_expression)); e->op = STR_OP_VARIABLE; e->str = name; e->left = NULL; e->right = NULL; log_msg(ast_log_level, "ast: new variable (%p): name: '%s'", (void*) e, name); return e; } string_expression* new_string_concat(string_expression* left, string_expression* right) { string_expression* e = checked_malloc(sizeof(string_expression)); e->op = STR_OP_CONCAT; e->str = NULL; e->left = left; e->right = right; log_msg(ast_log_level, "ast: new string concat (%p): left: %p, right: %p", (void*) e, (void*) left, (void*) right); return e; } void free_string(char * s) { if (s == NULL) { return; } log_msg(ast_log_level, "ast: free string %p", (void*) s); free(s); } void free_attribute_expression(attribute_expression *a) { if (a == NULL) { return; } free_attribute_expression(a->left); free_string(a->right); log_msg(ast_log_level, "ast: free attribute expression %p", (void*) a); free(a); } void free_string_expression(string_expression *s) { if (s == NULL) { return; } free_string_expression(s->left); free_string_expression(s->right); free_string(s->str); log_msg(ast_log_level, "ast: free string expression %p", (void*) s); free(s); } void free_bool_expression(bool_expression *b) { if (b == NULL) { return; } switch (b->op) { case BOOL_OP_NOT: free_bool_expression(b->left._bool); break; case BOOL_OP_EXISTS: case BOOL_OP_DEFINED: case BOOL_OP_HOSTNAME: free_string_expression(b->left._str); break; case BOOL_OP_VERSION_GE: free_string_expression(b->left._str); free_string_expression(b->right._str); break; } log_msg(ast_log_level, "ast: free bool expression %p", (void*) b); free(b); } void free_if_condition(if_condition *c) { free_bool_expression(c->expression); free_string(c->linebuf); log_msg(ast_log_level, "ast: free if condition %p", (void*) c); free(c); } void free_ft_restriction_expression(ft_restriction_expression *r) { if (r == NULL) { return; } free_ft_restriction_expression(r->left); free_string(r->right); log_msg(ast_log_level, "ast: free file type restriction expression %p", (void*) r); free(r); } void free_restriction_expression(restriction_expression *r) { if (r == NULL) { return; } #ifdef HAVE_FSTYPE free_string(r->fs_type); #endif free_ft_restriction_expression(r->f_types); log_msg(ast_log_level, "ast: free restriction expression %p", (void*) r); free(r); } void deep_free(ast* config_ast) { if (config_ast == NULL) { return; } ast* node = NULL; for(node = config_ast; node != NULL; ) { switch (node->type) { case config_option_type: free_attribute_expression(node->statement._config.a); free_string_expression(node->statement._config.e); break; case define_statement_type: free_string_expression(node->statement._define.value); free_string(node->statement._define.name); break; case group_statement_type: free_attribute_expression(node->statement._group.expr); free_string(node->statement._group.name); break; case if_statement_type: free_if_condition(node->statement._if.condition); deep_free(node->statement._if.if_branch); deep_free(node->statement._if.else_branch); break; case include_statement_type: free_string_expression(node->statement._include.path); free_string_expression(node->statement._include.rx); free_string_expression(node->statement._include.prefix); break; case x_include_setenv_statement_type: free_string_expression(node->statement._x_include_setenv.value); free_string(node->statement._x_include_setenv.variable); break; case rule_statement_type: free_string_expression(node->statement._rule.path); free_restriction_expression(node->statement._rule.restriction); free_attribute_expression(node->statement._rule.attributes); break; case undefine_statement_type: free_string(node->statement._define.name); break; } free(node->linebuf); ast* to_be_freed = node; node = node->next; log_msg(ast_log_level, "ast: free ast node %p (next: %p)", (void*) to_be_freed, (void*) node); free(to_be_freed); } } aide-0.19.3/src/base64.c0000644000175000017500000001372514774422002015761 0ustar00hvhaugwitzhvhaugwitz/* ** ** Copyright (C) 1994 Swedish University Network (SUNET) ** Modified by Rami Lehti (C) 1999 ** Modified by Richard van den Berg (C) 2005,2006 ** Modified by Hannes von Haugwitz (C) 2018,2020-2022,2024 ** ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** ** Martin.Wendel@udac.uu.se ** Torbjorn.Wictorin@udac.uu.se ** ** UDAC ** P.O. Box 174 ** S-751 04 Uppsala ** Sweden ** */ #include #include #include #include "base64.h" #include "util.h" #include "log.h" char tob64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int fromb64[] = { FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, SKIP, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, SKIP, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, 0x3e, FAIL, FAIL, FAIL, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, FAIL, FAIL, FAIL, SKIP, FAIL, FAIL, FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL }; /* Returns NULL on error */ char* encode_base64(byte* src,size_t ssize) { char* outbuf; int pos; int i, l, left; unsigned long triple; byte *inb; /* Exit on empty input */ if (!ssize||src==NULL){ log_msg(LOG_LEVEL_DEBUG,"encode base64: empty string"); return NULL; } /* length of encoded base64 string (padded) */ size_t length = sizeof(char)* ((ssize + 2) / 3) * 4; outbuf = (char *)checked_malloc(length + 1); /* Initialize working pointers */ inb = src; i = 0; triple = 0; pos = 0; left = ssize; log_msg(LOG_LEVEL_TRACE, "encode base64:, data length: %d", left); /* * Process entire inbuf. */ while (left != 0) { i++; left--; triple = (triple <<8) | *inb; if (i == 3 || left == 0) { switch (i) { case 1: triple = triple<<4; break; case 2: triple = triple<<2; break; default: break; } for (l = i; l >= 0; l--){ /* register */ int rr; rr = 0x3f & (triple>>(6*l)); assert (rr < 64); outbuf[pos]=tob64[rr]; pos++; } if (left == 0) switch(i) { case 2: outbuf[pos]='='; pos++; break; case 1: outbuf[pos]='='; pos++; outbuf[pos]='='; pos++; break; default: break; } triple = 0; i = 0; } inb++; } outbuf[pos]='\0'; return outbuf; } byte* decode_base64(char* src,size_t ssize, size_t *ret_len) { byte* outbuf; char* inb; int i; int l; int left; int pos; unsigned long triple; /* Exit on empty input */ if (!ssize||src==NULL) { log_msg(LOG_LEVEL_DEBUG, "decode base64: empty string"); return NULL; } /* exit on unpadded input */ if (ssize % 4) { log_msg(LOG_LEVEL_WARNING, "decode_base64: '%s' has invalid length (missing padding characters?)", src); return NULL; } /* calculate length of decoded string, substract padding chars if any (ssize is >= 4) */ size_t length = sizeof(byte) * ((ssize / 4) * 3)- (src[ssize-1] == '=') - (src[ssize-2] == '='); /* Initialize working pointers */ inb = src; outbuf = (byte *)checked_malloc(length + 1); l = 0; triple = 0; pos=0; left = ssize; /* * Process entire inbuf. */ while (left != 0) { left--; i = fromb64[(unsigned char)*inb]; switch(i) { case FAIL: log_msg(LOG_LEVEL_WARNING, "decode_base64: illegal character: '%c' in '%s'", *inb, src); free(outbuf); return NULL; break; case SKIP: break; default: triple = triple<<6 | (0x3f & i); l++; break; } if (l == 4 || left == 0) { switch(l) { case 2: triple = triple>>4; break; case 3: triple = triple>>2; break; default: break; } for (l -= 2; l >= 0; l--) { outbuf[pos]=( 0xff & (triple>>(l*8))); pos++; } triple = 0; l = 0; } inb++; } outbuf[pos]='\0'; if (ret_len) *ret_len = pos; return outbuf; } aide-0.19.3/src/fopen.c0000644000175000017500000002526514412055402016001 0ustar00hvhaugwitzhvhaugwitz/***************************************************************************** * * This example source code introduces a c library buffered I/O interface to * URL reads it supports fopen(), fread(), fgets(), feof(), fclose(), * rewind(). Supported functions have identical prototypes to their normal c * lib namesakes and are preceaded by url_ . * * Using this code you can replace your program's fopen() with url_fopen() * and fread() with url_fread() and it become possible to read remote streams * instead of (only) local files. Local files (ie those that can be directly * fopened) will drop back to using the underlying clib implementations * * See the main() function at the bottom that shows an app that retrives from a * specified url using fgets() and fread() and saves as two output files. * * Copyright (c) 2003 Simtec Electronics * * Re-implemented by Vincent Sanders with extensive * reference to original curl example code * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This example requires libcurl 7.9.7 or later. * * Modified for aide by Hannes von Haugwitz * based on modifications of previous version by Pablo Virolainen * (pablo@ipi.fi): * 2013-05-14: - moved declarations to 'include/fopen.h' * - removed (unneeded) main method * 2022-02-12: - update #include statements */ #include #include #include #include #include #include #include "fopen.h" /* we use a global one for convenience */ CURLM *multi_handle; /* curl calls this routine to get more data */ static size_t write_callback(char *buffer, size_t size, size_t nitems, void *userp) { char *newbuff; size_t rembuff; URL_FILE *url = (URL_FILE *)userp; size *= nitems; rembuff=url->buffer_len - url->buffer_pos; /* remaining space in buffer */ if(size > rembuff) { /* not enough space in buffer */ newbuff=realloc(url->buffer,url->buffer_len + (size - rembuff)); if(newbuff==NULL) { fprintf(stderr,"callback buffer grow failed\n"); size=rembuff; } else { /* realloc suceeded increase buffer size*/ url->buffer_len+=size - rembuff; url->buffer=newbuff; } } memcpy(&url->buffer[url->buffer_pos], buffer, size); url->buffer_pos += size; return size; } /* use to attempt to fill the read buffer up to requested number of bytes */ static int fill_buffer(URL_FILE *file, size_t want) { fd_set fdread; fd_set fdwrite; fd_set fdexcep; struct timeval timeout; int rc; /* only attempt to fill buffer if transactions still running and buffer * doesnt exceed required size already */ if((!file->still_running) || (file->buffer_pos > want)) return 0; /* attempt to fill buffer */ do { int maxfd = -1; long curl_timeo = -1; FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); /* set a suitable timeout to fail on */ timeout.tv_sec = 60; /* 1 minute */ timeout.tv_usec = 0; curl_multi_timeout(multi_handle, &curl_timeo); if(curl_timeo >= 0) { timeout.tv_sec = curl_timeo / 1000; if(timeout.tv_sec > 1) timeout.tv_sec = 1; else timeout.tv_usec = (curl_timeo % 1000) * 1000; } /* get file descriptors from the transfers */ curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); /* In a real-world program you OF COURSE check the return code of the function calls. On success, the value of maxfd is guaranteed to be greater or equal than -1. We call select(maxfd + 1, ...), specially in case of (maxfd == -1), we call select(0, ...), which is basically equal to sleep. */ rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); switch(rc) { case -1: /* select error */ break; case 0: default: /* timeout or readable/writable sockets */ curl_multi_perform(multi_handle, &file->still_running); break; } } while(file->still_running && (file->buffer_pos < want)); return 1; } /* use to remove want bytes from the front of a files buffer */ static int use_buffer(URL_FILE *file,int want) { /* sort out buffer */ if((file->buffer_pos - want) <=0) { /* ditch buffer - write will recreate */ if(file->buffer) free(file->buffer); file->buffer=NULL; file->buffer_pos=0; file->buffer_len=0; } else { /* move rest down make it available for later */ memmove(file->buffer, &file->buffer[want], (file->buffer_pos - want)); file->buffer_pos -= want; } return 0; } URL_FILE *url_fopen(const char *url,const char *operation) { /* this code could check for URLs or types in the 'url' and basicly use the real fopen() for standard files */ URL_FILE *file; (void)operation; file = malloc(sizeof(URL_FILE)); if(!file) return NULL; memset(file, 0, sizeof(URL_FILE)); if((file->handle.file=fopen(url,operation))) file->type = CFTYPE_FILE; /* marked as URL */ else { file->type = CFTYPE_CURL; /* marked as URL */ file->handle.curl = curl_easy_init(); curl_easy_setopt(file->handle.curl, CURLOPT_URL, url); curl_easy_setopt(file->handle.curl, CURLOPT_WRITEDATA, file); curl_easy_setopt(file->handle.curl, CURLOPT_VERBOSE, 0L); curl_easy_setopt(file->handle.curl, CURLOPT_WRITEFUNCTION, write_callback); if(!multi_handle) multi_handle = curl_multi_init(); curl_multi_add_handle(multi_handle, file->handle.curl); /* lets start the fetch */ curl_multi_perform(multi_handle, &file->still_running); if((file->buffer_pos == 0) && (!file->still_running)) { /* if still_running is 0 now, we should return NULL */ /* make sure the easy handle is not in the multi handle anymore */ curl_multi_remove_handle(multi_handle, file->handle.curl); /* cleanup */ curl_easy_cleanup(file->handle.curl); free(file); file = NULL; } } return file; } int url_fclose(URL_FILE *file) { int ret=0;/* default is good return */ switch(file->type) { case CFTYPE_FILE: ret=fclose(file->handle.file); /* passthrough */ break; case CFTYPE_CURL: /* make sure the easy handle is not in the multi handle anymore */ curl_multi_remove_handle(multi_handle, file->handle.curl); /* cleanup */ curl_easy_cleanup(file->handle.curl); break; default: /* unknown or supported type - oh dear */ ret=EOF; errno=EBADF; break; } if(file->buffer) free(file->buffer);/* free any allocated buffer space */ free(file); return ret; } int url_feof(URL_FILE *file) { int ret=0; switch(file->type) { case CFTYPE_FILE: ret=feof(file->handle.file); break; case CFTYPE_CURL: if((file->buffer_pos == 0) && (!file->still_running)) ret = 1; break; default: /* unknown or supported type - oh dear */ ret=-1; errno=EBADF; break; } return ret; } size_t url_fread(void *ptr, size_t size, size_t nmemb, URL_FILE *file) { size_t want; switch(file->type) { case CFTYPE_FILE: want=fread(ptr,size,nmemb,file->handle.file); break; case CFTYPE_CURL: want = nmemb * size; fill_buffer(file,want); /* check if theres data in the buffer - if not fill_buffer() * either errored or EOF */ if(!file->buffer_pos) return 0; /* ensure only available data is considered */ if(file->buffer_pos < want) want = file->buffer_pos; /* xfer data to caller */ memcpy(ptr, file->buffer, want); use_buffer(file,want); want = want / size; /* number of items */ break; default: /* unknown or supported type - oh dear */ want=0; errno=EBADF; break; } return want; } char *url_fgets(char *ptr, size_t size, URL_FILE *file) { size_t want = size - 1;/* always need to leave room for zero termination */ size_t loop; switch(file->type) { case CFTYPE_FILE: ptr = fgets(ptr,size,file->handle.file); break; case CFTYPE_CURL: fill_buffer(file,want); /* check if theres data in the buffer - if not fill either errored or * EOF */ if(!file->buffer_pos) return NULL; /* ensure only available data is considered */ if(file->buffer_pos < want) want = file->buffer_pos; /*buffer contains data */ /* look for newline or eof */ for(loop=0;loop < want;loop++) { if(file->buffer[loop] == '\n') { want=loop+1;/* include newline */ break; } } /* xfer data to caller */ memcpy(ptr, file->buffer, want); ptr[want]=0;/* allways null terminate */ use_buffer(file,want); break; default: /* unknown or supported type - oh dear */ ptr=NULL; errno=EBADF; break; } return ptr;/*success */ } void url_rewind(URL_FILE *file) { switch(file->type) { case CFTYPE_FILE: rewind(file->handle.file); /* passthrough */ break; case CFTYPE_CURL: /* halt transaction */ curl_multi_remove_handle(multi_handle, file->handle.curl); /* restart */ curl_multi_add_handle(multi_handle, file->handle.curl); /* ditch buffer - write will recreate - resets stream pos*/ if(file->buffer) free(file->buffer); file->buffer=NULL; file->buffer_pos=0; file->buffer_len=0; break; default: /* unknown or supported type - oh dear */ break; } } aide-0.19.3/src/list.c0000644000175000017500000001217414412055402015640 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2002, 2005-2006, 2010, 2019-2020, 2023 Rami Lehti, * Pablo Virolainen, Richard van den Berg, Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "list.h" #include "log.h" #include "util.h" /*for locale support*/ /* list * limitations: * Only the head knows where the tail is * Every item knows where the head is * And that is not true anymore. * Now list has header which knows head and tail. * Every item knows header. */ /* list_sorted_insert() * Adds an item in a sorted list: * - The first argument is the head of the list * - The second argument is the data to be added * - The third argument is the function pointer to the compare function to use * - Returns the head of the list */ list* list_sorted_insert(list* listp, void* data, int (*compare) (const void*, const void*)) { list* newitem=NULL; list* curitem=NULL; newitem = checked_malloc(sizeof(list)); if (listp==NULL){ list_header* header = checked_malloc(sizeof(list_header)); newitem->data=data; newitem->header=header; newitem->next=NULL; newitem->prev=NULL; header->head=newitem; header->tail=newitem; return newitem; } else { /* add element in sorted, non-empty list (use insertion sort) */ curitem = listp->header->head; newitem->header=listp->header; newitem->data=data; if (compare(newitem->data,curitem->data) <= 0) { /* new element is the new head */ listp->header->head=newitem; curitem->prev=newitem; newitem->next=curitem; newitem->prev=NULL; return newitem; } else { /* find position for new element */ while(compare(newitem->data, curitem->data) > 0 && curitem->next != NULL) { curitem=curitem->next; } if (curitem->next == NULL && compare(newitem->data, curitem->data) > 0) { /* new element is the new tail */ listp->header->tail=newitem; curitem->next=newitem; newitem->prev=curitem; newitem->next=NULL; } else { /* new element is an inner element */ curitem->prev->next=newitem; newitem->prev=curitem->prev; curitem->prev=newitem; newitem->next=curitem; } } return listp; } } /* list_append() * append an item to list * returns the head * The first argument is the head of the list * The second argument is the data to be added * Returns list head */ list* list_append(list* listp,void*data) { list* newitem=NULL; newitem = checked_malloc(sizeof(list)); if(listp==NULL){ list_header* header = checked_malloc(sizeof(list_header)); newitem->data=data; newitem->header=header; newitem->next=NULL; newitem->prev=NULL; header->head=newitem; header->tail=newitem; return newitem; }else { /* We have nonempty list. * add to last */ newitem->prev=listp->header->tail; newitem->next=NULL; newitem->data=data; newitem->header=listp->header; listp->header->tail->next=newitem; listp->header->tail=newitem; return listp; } /* Not reached */ return NULL; } /* * delete_list_item() * delete a item from list * returns head of a list. */ list* list_delete_item(list* item){ list* r; if (item==NULL) { log_msg(LOG_LEVEL_DEBUG, "tried to remove from empty list"); return item; } if (item->header->head==item->header->tail) { /* * Ollaan poistamassa listan ainoaa alkiota. * Tllin palautetaan NULL */ free(item->header); free(item); return NULL; } /* * Nyt meill on listassa ainakin kaksi alkiota * */ /* poistetaan listan viimeist alkiota */ if (item==item->header->tail){ r=item->prev; item->header->tail=r; r->next=NULL; r=r->header->head; free(item); return r; } /* * Poistetaan listan ensimminen alkio. */ if (item==item->header->head) { r=item->next; item->header->head=r; r->prev=NULL; r=r->header->head; free(item); return r; } r=item->prev; item->prev->next=item->next; item->next->prev=item->prev; free(item); r=r->header->head; return r; } aide-0.19.3/src/db_file.c0000644000175000017500000005350415046172541016263 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2007, 2010-2013, 2016, 2018-2025 Rami Lehti, * Pablo Virolainen, Mike Markley, Richard van den Berg, * Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include "aide.h" #include #include #include #include #include #include #include #include #include "db_config.h" #include "gen_list.h" #include "hashsum.h" #include "log.h" #include "progress.h" #include "url.h" #include "db.h" #ifdef WITH_CURL #include "fopen.h" #endif #include "attributes.h" #include #include "base64.h" #include "db_line.h" #include "db_file.h" #include "util.h" #include "errorcodes.h" #ifdef WITH_ZLIB #include #endif #define BUFSIZE 16384 #include "md.h" static bool db_parse_spec(database* db, char **saveptr){ char *token = NULL; DB_ATTR_TYPE seen_attrs = 0LLU; db->fields = checked_malloc(1*sizeof(ATTRIBUTE)); while ((token = strtok_r(NULL, " ", saveptr)) != NULL) { if (strncmp("@@", token, 2) == 0) { LOG_DB_FORMAT_LINE(LOG_LEVEL_ERROR, "unexpected token while reading db_spec: '%s'", token); return false; } else { ATTRIBUTE l; db->fields = checked_realloc(db->fields, (db->num_fields+1)*sizeof(ATTRIBUTE)); db->fields[db->num_fields]=attr_unknown; for (l=0;lnum_fields) db->fields[db->num_fields]=attr_unknown; } else { db->fields[db->num_fields]=l; seen_attrs |= ATTR(l); LOG_DB_FORMAT_LINE(LOG_LEVEL_DEBUG, "@@db_spec: define field '%s' at position %i", token, db->num_fields) } db->num_fields++; break; } } if(l==attr_unknown){ LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "@@db_spec: skip unknown field '%s' at position %i", token, db->num_fields); db->fields[db->num_fields]=attr_unknown; db->num_fields++; } } } /* Lets generate attr from db_order if database does not have attr */ conf->attr=DB_ATTR_UNDEF; for (int i=0;inum_fields;i++) { if (db->fields[i] == attr_attr) { conf->attr=1; } } if (conf->attr==DB_ATTR_UNDEF) { conf->attr=0; for(int i=0;inum_fields;i++) { conf->attr|=1LL<fields[i]; } char *str; LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "missing attr field, generated attr field from dbspec: %s (comparison may be incorrect)", str = diff_database_attributes(0, conf->attr)) free(str); } return true; } static char *fgets_wrapper(char *ptr, size_t size, database *db) { char * buf = NULL; #ifdef WITH_CURL switch ((db->url)->type) { case url_http: case url_https: case url_ftp: { buf = url_fgets(ptr, size, (URL_FILE *)db->fp); if (!buf) { log_msg(LOG_LEVEL_ERROR, "url_fgets failed for %s", (db->url)->raw); exit(IO_ERROR); } break; } default: #endif #ifdef WITH_ZLIB if (db->gzp == NULL) { db->gzp=gzdopen(fileno((FILE *)db->fp),"rb"); if (db->gzp == NULL) { log_msg(LOG_LEVEL_ERROR, "gzdopen failed for %s", (db->url)->raw); exit(IO_ERROR); } } buf = gzgets(db->gzp, ptr, size); if (!buf && !gzeof(db->gzp)) { int gzerrnum; log_msg(LOG_LEVEL_ERROR, "gzgets failed for %s: %s", (db->url)->raw, gzerror(db->gzp, &gzerrnum)); exit(IO_ERROR); } #else buf = fgets(ptr, size, db->fp); if (ferror(db->fp)) { log_msg(LOG_LEVEL_ERROR, "fgets failed for %s: %s", (db->url)->raw, strerror(errno)); exit(IO_ERROR); } #endif #ifdef WITH_CURL } #endif if (buf && db->mdc) { update_md(db->mdc, buf, strlen(buf)); } return buf; } static char *get_next_dbline(database *db) { char buffer[2048]; char *line = NULL; size_t len = 0; while (fgets_wrapper(buffer, sizeof(buffer), db) != NULL) { size_t buffer_len = strlen(buffer); line = checked_realloc(line, buffer_len + len + 1); strncpy(line + len, buffer, buffer_len+1); len += buffer_len; /* remove newline character */ if (line[len-1] == '\n') { line[len-1] = '\0'; break; } } return line; } db_entry_t db_readline_file(database* db, bool include_limited_entries) { char **s = NULL; char *saveptr, *token; char *line = NULL; db_entry_t entry = { .line = NULL, .limit = false }; while ((line = get_next_dbline(db)) != NULL) { db->lineno++; LOG_LEVEL db_parse_log_level = LOG_LEVEL_DEBUG; switch (line[0]) { case '#': LOG_DB_FORMAT_LINE(db_parse_log_level, "db_read_file: skip comment line: '%s'", line) break; case '\0': LOG_DB_FORMAT_LINE(db_parse_log_level, "%s", "db_read_file: skip empty line") break; default: saveptr = NULL; token = strtok_r(line, " ", &saveptr); if (strcmp("@@db_spec", token) == 0) { if (db->fields) { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip additional '%s' line", token) } else { LOG_DB_FORMAT_LINE(db_parse_log_level, "db_read_file: parse '%s'", token) db_parse_spec(db, &saveptr); } } else if (strcmp("@@begin_db", token) == 0) { if (db->flags&DB_FLAG_PARSE) { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip additional '%s' line", token) } else { LOG_DB_FORMAT_LINE(db_parse_log_level, "%s", "db_read_file: start reading database (found '@@begin_db')") db->flags |= DB_FLAG_PARSE; } if ((token = strtok_r(NULL, "\n", &saveptr)) != NULL) { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip unexpected string after '@@begin_db': '%s'", token) } } else if (strcmp("@@end_db", token) == 0) { if (db->flags&DB_FLAG_PARSE) { db->flags &= ~(DB_FLAG_PARSE); LOG_DB_FORMAT_LINE(db_parse_log_level, "%s", "db_read_file: stop reading database (found '@@end_db')") if ((token = strtok_r(NULL, "\n", &saveptr)) != NULL) { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip unexpected string after '@@end_db': '%s'", token) } return entry; } else { LOG_DB_FORMAT_LINE(LOG_LEVEL_ERROR, "%s", "unexpected '@@end_db', expected '@@begin_db'") exit(DATABASE_ERROR); } } else if (db->flags&DB_FLAG_PARSE) { if (*token != '/') { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip line with invalid path: '%s'", token) break; } else { if (check_limit(token, true, NULL)) { if (include_limited_entries) { entry.limit = true; db_parse_log_level = LOG_LEVEL_LIMIT; } else { progress_status(PROGRESS_SKIPPED, NULL); break; } } LOG_DB_FORMAT_LINE(db_parse_log_level, "db_read_file: parse '%s'", token) s = checked_malloc(sizeof(char*)*num_attrs); for(ATTRIBUTE j=0; j= db->num_fields) { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip unexpected string '%s')", token); } else if (db->fields[i] != attr_unknown) { s[db->fields[i]] = checked_strdup(token); LOG_DB_FORMAT_LINE(db_parse_log_level, "db_read_file: '%s' set field '%s' (position %d): '%s'", s[0], attributes[db->fields[i]].db_name, i, token) } else { LOG_DB_FORMAT_LINE(db_parse_log_level, "skip unknown/redefined field at position: %d: '%s'", i, token); } token = strtok_r(NULL, " ", &saveptr); i++; } if (inum_fields) { LOG_DB_FORMAT_LINE(LOG_LEVEL_WARNING, "skip cutoff database line '%s' found (field '%s' (position: %d) is missing)", s[0], attributes[db->fields[i]].db_name, i) for(int a=0;afields[a]]); s[db->fields[a]] = NULL; } free(s); s = NULL; } else { entry.line = db_char2line(s, db); for(int j=0;jnum_fields;j++){ if(db->fields[j]!=attr_unknown && s[db->fields[j]]!=NULL){ free(s[db->fields[j]]); s[db->fields[j]]=NULL; } } free(s); return entry; } } } else { LOG_DB_FORMAT_LINE(db_parse_log_level, "skip line '%s' ('@@begin_db' not (yet) found)", line) } } free(line); line = NULL; } if (db->flags&DB_FLAG_PARSE) { LOG_DB_FORMAT_LINE(LOG_LEVEL_ERROR, "%s", "missing '@@end_db' (incomplete database file)") exit(DATABASE_ERROR); } else { /* empty database */ return entry; } } static int str_format(char *, int n, const char*, ...) #ifdef __GNUC__ __attribute__ ((format (printf, 3, 4))) #endif ; static int str_format(char *str, int n, const char* format, ...) { va_list ap; va_start(ap, format); int len = vsnprintf(NULL, 0, format, ap); va_end(ap); if (str) { va_start(ap, format); vsnprintf(&str[n], len+1, format, ap); va_end(ap); } return len; } static int str_filename(char *str, int n, char *path) { char *safe_path = NULL; int len = 0; if (contains_unsafe(path)) { safe_path = encode_string(path); } len = str_format(str, n+len, "%s", safe_path?safe_path:path); free(safe_path); return len; } static int str_linkname(char *str, int n, char *path) { char *safe_path = NULL; int len = 0; if (path == NULL) { len = str_format(str, n, " %s", "0"); return len; } if (*path == '\0') { len = str_format(str, n, " %s", "0-"); return len; } if (contains_unsafe(path)) { safe_path = encode_string(path); } len += str_format(str, n, " %s%s", *path == '0'?"0":"", safe_path?safe_path:path); free(safe_path); return len; } static int byte_base64(char *str, int n, byte *src, int src_len) { char *enc = src ? encode_base64(src, src_len) : NULL; int len = str_format(str, n, " %s", enc ? enc : "0"); free(enc); return len; } #define CASE_BYTE_BASE64(attr, src, src_len) case attr : { n += byte_base64(str, n, src, src_len); break; } #define CASE_HASHSUM(x) CASE_BYTE_BASE64(attr_ ##x, line->hashsums[hash_ ##x], hashsums[hash_ ##x].length) #ifdef WITH_XATTR static int str_xattr(char *str, int n, xattrs_type *xattrs) { if (xattrs) { size_t m = 0; m = str_format(str, n, " %lu", xattrs->num); xattr_node *xattr = xattrs->ents; for (size_t i = xattrs->num; i > 0; --i) { char *enc_key = NULL; if (contains_unsafe(xattr->key)) { enc_key = encode_string(xattr->key); } char *enc_value = encode_base64(xattr->val, xattr->vsz); m += str_format(str, n + m, ",%s,%s", enc_key?enc_key:xattr->key, enc_value?enc_value:"0"); free(enc_key); free(enc_value); ++xattr; } return m; } else { return str_format(str, n, " %lu", 0LU); } } #endif #ifdef WITH_ACL static int str_acl(char *str, int n, acl_type *acl) { #ifdef WITH_POSIX_ACL if (acl) { char *enc_acl_a = acl->acl_a ? encode_base64((byte *)acl->acl_a, strlen(acl->acl_a)) : NULL; char *enc_acl_d = acl->acl_d ? encode_base64((byte *)acl->acl_d, strlen(acl->acl_d)) : NULL; int len = str_format(str, n, " %s,%s,%s", "POSIX", enc_acl_a ? enc_acl_a : "0", enc_acl_d ? enc_acl_d : "0"); free(enc_acl_d); free(enc_acl_a); return len; } else { return str_format(str, n, " %lu", 0LU); } #endif } #endif static int construct_database_line(db_line *line, char *str) { int n = 0; for (ATTRIBUTE i = 0; i < num_attrs; ++i) { if (attributes[i].db_name && ATTR(i) & conf->db_out_attrs) { switch (i) { case attr_filename: { n += str_filename(str, n, line->filename); break; } case attr_attr: { n += str_format(str, n, " %llu", line->attr); break; } case attr_inode: { n += str_format(str, n, " %li", line->inode); break; } case attr_size: { n += str_format(str, n, " %lli", line->size); break; } case attr_bcount: { n += str_format(str, n, " %lli", line->bcount); break; } case attr_perm: { n += str_format(str, n, " %lo", (long)line->perm); break; } case attr_uid: { n += str_format(str, n, " %li", line->uid); break; } case attr_gid: { n += str_format(str, n, " %li", line->gid); break; } case attr_atime: { n += str_format(str, n, " %ld", (long)line->atime); break; } case attr_ctime: { n += str_format(str, n, " %ld", (long)line->ctime); break; } case attr_mtime: { n += str_format(str, n, " %ld", (long)line->mtime); break; } case attr_linkname: { n += str_linkname(str, n, line->linkname); break; ; } case attr_linkcount: { n += str_format(str, n, " %li", line->nlink); break; } CASE_HASHSUM(md5) CASE_HASHSUM(sha1) CASE_HASHSUM(rmd160) CASE_HASHSUM(tiger) CASE_HASHSUM(crc32) CASE_HASHSUM(crc32b) CASE_HASHSUM(haval) CASE_HASHSUM(gostr3411_94) CASE_HASHSUM(stribog256) CASE_HASHSUM(stribog512) CASE_HASHSUM(sha256) CASE_HASHSUM(sha512) CASE_HASHSUM(whirlpool) CASE_HASHSUM(sha512_256) CASE_HASHSUM(sha3_256) CASE_HASHSUM(sha3_512) case attr_acl: { #ifdef WITH_ACL n += str_acl(str, n, line->acl); #endif break; } case attr_xattrs: { #ifdef WITH_XATTR n += str_xattr(str, n, line->xattrs); #endif break; } case attr_selinux: { #ifdef WITH_SELINUX n += byte_base64(str, n, (byte *)line->cntx, line->cntx ? strlen(line->cntx) : 0); #endif break; } case attr_e2fsattrs: { #ifdef WITH_E2FSATTRS n += str_format(str, n, " %lu", line->e2fsattrs); #endif break; } case attr_capabilities: { #ifdef WITH_CAPABILITIES n += byte_base64(str, n, (byte *)line->capabilities, line->capabilities ? strlen(line->capabilities) : 0); #endif break; } case attr_fs_type : { #ifdef HAVE_FSTYPE n += str_format(str, n, " %llu", (unsigned long long) line->fs_type); #endif break; } case attr_ftype: case attr_bsize: case attr_rdev: case attr_dev: case attr_allhashsums: case attr_sizeg: case attr_checkinode: case attr_allownewfile: case attr_allowrmfile: case attr_growing: case attr_compressed: case attr_unknown: { /* nothing to write to database */ break; } } } } if (str) { snprintf(&str[n], 2, "\n"); } n++; return n; } static void handle_io_error_on_write(char *function_str) { if (conf->database_out.url->type == url_file && conf->database_out.flags&DB_FLAG_CREATED) { log_msg(LOG_LEVEL_ERROR, "%s failed for %s (remove incompletely written database)", function_str, ((conf->database_out).url)->raw); unlink(conf->database_out.url->value); } else { log_msg(LOG_LEVEL_ERROR, "%s failed for %s", function_str, ((conf->database_out).url)->raw); } exit(IO_ERROR); } static void db_out_write(char * str, size_t len) { if ((conf->database_out).mdc) { update_md((conf->database_out).mdc, str, len); } #ifdef WITH_ZLIB if(conf->gzip_dbout) { if (gzwrite((conf->database_out).gzp, str, len) < (int) len) { handle_io_error_on_write("gzwrite"); } } else { #endif if (fwrite(str, sizeof(char), len, conf->database_out.fp) < len) { handle_io_error_on_write("fwrite"); } if (fflush(conf->database_out.fp) != 0) { handle_io_error_on_write("fflush"); } #ifdef WITH_ZLIB } #endif } int db_writeline_file(db_line* line) { char *str = NULL; int n = construct_database_line(line, str); str = checked_malloc(n+1); construct_database_line(line, str); db_out_write(str, n); free(str); return RETOK; } static int construct_database_header(db_config *dbconf, char *str) { int n = 0; n += str_format(str, n, "%s", "@@begin_db\n"); if (dbconf->database_add_metadata) { time_t db_gen_time = time(NULL); char *time_str = get_time_string(&db_gen_time); n += str_format(str, n, "# This file was generated by Aide, version %s\n" "# Time of generation was %s\n", conf->aide_version, time_str); free(time_str); } if (dbconf->config_version) { n += str_format(str, n, "# The config version used to generate this file was:\n" "# %s\n", dbconf->config_version); } n += str_format(str, n, "%s", "@@db_spec"); for (ATTRIBUTE i = 0; i < num_attrs; ++i) { if (attributes[i].db_name && attributes[i].attr & conf->db_out_attrs) { n += str_format(str, n, " %s", attributes[i].db_name); } } n += str_format(str, n, "%s", "\n"); return n; } int db_writespec_file(db_config* dbconf) { char *str = NULL; int n = construct_database_header(dbconf, str); str = checked_malloc(n+1); construct_database_header(dbconf, str); db_out_write(str, n); free(str); return RETOK; } int db_close_file(db_config* dbconf){ if(dbconf->database_out.fp #ifdef WITH_ZLIB || dbconf->database_out.gzp #endif ){ char *end_db_str = "@@end_db\n"; db_out_write(end_db_str, strlen(end_db_str)); } #ifdef WITH_ZLIB if(dbconf->gzip_dbout){ if(gzclose(dbconf->database_out.gzp)){ log_msg(LOG_LEVEL_ERROR,"unable to gzclose database '%s': %s", (dbconf->database_out.url)->raw, strerror(errno)); return RETFAIL; } dbconf->database_out.gzp = NULL; }else { #endif if(fclose(dbconf->database_out.fp)){ log_msg(LOG_LEVEL_ERROR,"unable to close database '%s': %s", (dbconf->database_out.url)->raw, strerror(errno)); return RETFAIL; } dbconf->database_out.fp = NULL; #ifdef WITH_ZLIB } #endif return RETOK; } // vi: ts=8 sw=8 aide-0.19.3/src/url.c0000644000175000017500000000304314412055402015462 0ustar00hvhaugwitzhvhaugwitz/* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 2020 Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "url.h" #include struct url_type { URL_TYPE type; const char *string; }; static struct url_type url_type_array[] = { { url_file, "file" }, { url_stdout, "stdout" }, { url_stdin, "stdin" }, { url_stderr, "stderr" }, { url_fd, "fd" }, { url_ftp, "ftp" }, { url_http, "http" }, { url_https, "https" }, { url_syslog, "syslog" }, }; int num_url_types = sizeof(url_type_array)/sizeof(struct url_type); URL_TYPE get_url_type(char * str) { for (int i = 0; i < num_url_types; ++i) { if (strcmp(str, url_type_array[i].string) == 0) { return url_type_array[i].type; } } return 0; } const char* get_url_type_string(URL_TYPE type) { return url_type_array[type-1].string; } aide-0.19.3/src/conf_yacc.y0000644000175000017500000002147014774422002016643 0ustar00hvhaugwitzhvhaugwitz%code requires { #include "conf_ast.h" } %{ /* * AIDE (Advanced Intrusion Detection Environment) * * Copyright (C) 1999-2006, 2010-2013, 2015-2016, 2019-2025 Rami Lehti, * Pablo Virolainen, Richard van den Berg, Hannes von Haugwitz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include #include "attributes.h" #include #include #include "log.h" #include "rx_rule.h" #include "conf_lex.h" DB_ATTR_TYPE retval=0; #include "conf_ast.h" extern int conflex(void); void conferror(ast**, const char *); %} %union { char* s; config_option option; bool_operator operator; ast* ast; if_condition* if_cond; bool_expression* bool_expr; attribute_expression* attr_expr; restriction_expression* rs_expr; ft_restriction_expression* ft_rs_expr; string_expression* string_expr; } %token TDEFINE "@@define" %token TUNDEFINE "@@undef" %token TIFDEF "@@ifdef" %token TIFNDEF "@@ifndef" %token TIFNHOST "@@ifnhost" %token TIFHOST "@@ifhost" %token TIF "@@if" %token TBOOLNOT "not" %token TBOOLFUNC "boolean function" %token TBOOLOP "boolean operator" %token TELSE "@@else" %token TENDIF "@@endif" %token TINCLUDE "@@include" %token TXINCLUDE "@@x_include" %token TSETENV "@@x_include_setenv" %token TGROUP "group name" %token TSTRING "string" %token TEXPR "group" %token TVARIABLE "variable name" %token TSPACE "whitespace" %token TNEWLINE "new line" /* File rule */ %token TSELRXRULE "regular rule" %token TEQURXRULE "equals rule" %token TRECNEGRXRULE "recursive negative rule" %token TNONRECNEGRXRULE "non-recursive negative rule" %token