[
  {
    "path": ".editorconfig",
    "content": "# See: https://editorconfig.org/\n\nroot = true\n\n[*]\nindent_style = space\nindent_size = 4\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**Version**\n - Distribution [e.g. Ubuntu 18.04]\n - Lynis version [e.g. 2.7.0]\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Output**\nIf applicable, add output that you get from the tool or the related section of lynis.log\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. How would it help you to make things easier? Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Required changes**\nWhat needs to be changed in Lynis?\n\n**Additional context**\nAdd anything else that you consider to be relevant about the feature request here.\n"
  },
  {
    "path": ".github/workflows/publiccode-yml-validation.yml",
    "content": "name: publiccode.yml validation\n\non:\n    pull_request:\n        paths:\n            - publiccode.yml\n    push:\n        paths:\n            - publiccode.yml\n\njobs:\n    publiccode_yml_validation:\n        runs-on: ubuntu-latest\n        steps:\n            - uses: actions/checkout@v4\n            - uses: italia/publiccode-parser-action@v1\n              with:\n                  publiccode: \"publiccode.yml\"\n"
  },
  {
    "path": ".gitignore",
    "content": ".bzr\n.bzrignore\n.DS_Store\ncustom.prf\n*.swp\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: bash\n\nbefore_script:\n    - sh extras/travis-ci/before_script.sh\n\nscript:\n    - cd .. && cd ./lynis-sdk && sh lynis-devkit run unit-tests\n\nnotifications:\n  email:\n    recipients:\n      - lynis-dev@cisofy.com\n    on_success: change\n    on_failure: always\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Lynis Changelog\n\n## Lynis 3.1.7 (not released yet)\n\n### Changed\n- Detection of CachyOS\n- Updated end-of-life-database\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.6 (2025-10-22)\n\n### Added\n- Add notice to screen output if end-of-life state is unclear\n- Support for CachyOS, macOS Tahoe, and OpenMandriva Lx\n\n### Changed\n- Releases are now considered to be old if they are 6 months or older\n- Removed generic suggestion for outdated/old Lynis release, instead show to screen output\n- Generic clarifications on variable usage for operating system and its version \n- Updated end-of-life database\n- Updated Japanese translation\n- For Debian and similar systems ignore kernel packages with 'rc' state\n- ACCT-9634 - Define default auditd log file location\n- FIRE-4586 - Also accept NFLOG as a logging target for iptables\n- MALW-3280 - Adjusted detection of Wazuh agent\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.5 (2025-07-29)\n\n### Added\n- Support for OpenWrt\n- Bitdefender detection on Linux\n- Detection of openSUSE Tumbleweed-Slowroll\n\n### Changed\n- Corrected detection of service manager SMF\n- Extended GetHostID function to allow HostID and HostID2 creation on OpenWrt\n- Check modules also under /usr/lib/modules.d\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.4 (2025-01-28)\n\n### Changed\n- Update of translations: Portuguese\n- Add macOS Sequoia\n- Update of EOL database\n- Bugfix for using slashes in parameters (SafeInput function)\n- Simplified copyright line and meta data in files\n- Support for powerpc64le in authentication section\n- Don't show error \"kadmin.local: unable to get default realm\"\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.3 (2024-12-16)\n\nThis release introduces additional documentation in the form of blog articles\nto support the (missing) control information on the website. \n\n### Added\n- Detection of Buildroot, Fedora Linux Asahi Remix, Garden Linux, Peppermint OS\n- Support for blog posts and articles to enhance suggestions\n\n### Changed\n- BOOT-5264 - Changed output of systemd-analyze test and added link\n- FILE-6398 - Test temporarily disabled as on modern kernels JDB support is built-in\n- FIRE-4508 - Several changes to expand the test, make it more generic, resolve minor issues\n- KRNL-5622 - Test if systemctl binary is set\n- Several improvements for busybox\n- Update of translations: Italian, Russian, Spanish\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.2 (2024-09-26)\n\n### Added\n- Detection of ALT Linux\n- Detection of Athena OS\n- Detection of Container-Optimized OS from Google\n- Detection of Koozali SME Server\n- Detection of Nobara Linux\n- Detection of Open Source Media Center (OSMC)\n- Detection of PostmarketOS\n- CRYP-7932 - macOS FileVault encryption test\n- FILE-6398 - Check if JBD (Journal Block Device) driver is loaded\n- FINT-4344 - Wazuh system running state\n- PKGS-7305 - Query macOS Apps in /Applications and CoreServices\n- File added: .editorconfig, which is used by editors to standardize formatting\n\n### Changed\n- Correction of software EOL database and inclusion of AIX entries\n- Support sysctl value perf_event_paranoid -> 2|3\n- Update of translations: German, Portuguese, Turkish\n- Grammar and spell improvements\n- Improved package detection on Alpine Linux\n- Slackware support to check installed packges (functionPackageIsInstalled())\n- Added words prosecute/report to LEGAL_BANNER_STRINGS\n- Busybox support: Replace newer tr command syntax with older ascii specific operations\n- Added Wazuh as a malware scanner/antivirus and rootkit detection tool\n- Updated PHP versions and removed PHP 5 (deprecated)\n- AUTH-9262 - Corrected message with advised PAM libary (libpam-passwdqc)\n- CONT-8104 - Checking for errors, not only warning in docker info output\n- DBS-1826 - PostgreSQL detection improved for AlmaLinux, Rocky Linux, and FreeBSD\n- FILE-6344 - Test kernel version (major/minor)\n- INSE-8000 - Added inetd package and service name used in ubuntu 24.04\n- KRNL-5622 - Use systemctl get-default instead of following link\n- KRNL-5820 - Accept ulimit with -H parameter also\n- LOGG-2144 - Check for wazuh-agent presence on Linux systems\n- MACF-6234 - Test if semanage binary is available\n- MALW-3200 - ESET Endpoint Antivirus added\n- MALW-3280 - McAfee Antivirus for Linux deprecated\n- MALW-3291 - Check if Microsoft Defender Antivirus is installe\n- NETW-3200 - Added regex to allow both /bin/true as /bin/false\n- PKGS-7303 - Added version numbers to brew packages\n- PKGS-7370 - Cron job check for debsums improved\n- PKGS-7392 - Improved filtering of apt-check output (Ubuntu 24.04 may give an error)\n- PKGS-7410 - Added kernel name for Hardkernel odroid XU4\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.1 (2024-03-17)\n\n### Added\n- Detection of ArcoLinux\n\n### Changed\n- DBS-1882 - Redis configuration file path added for FreeBSD (/usr/local/etc/redis.conf)\n- DBS-1882 - Check /snap directory location for Redis configuration file\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.1.0 (2024-03-11)\n\n### Added\n- Translation: Indonesian\n\n### Changed\n- MALW-3280 - Correction to detect com.avast.daemon\n- OS detection added for Guix System, macOS Ventura (13.x)/Sonoma (14.x), NXP LSDK, OpenEmbedded \"nodistro\", and The Yocto Projects distro \"Poky\"\n- Updated Amazon Linux EOL dates and addition of Amazon Linux 2023\n- STATUS_NOT_ACTIVE variable added to translation files\n- End-of-life dates updated\n- Fixing missing or erroneous test number comments\n- Detection of SentinelOne corrected\n- Wazuh for file integrity and tooling\n- Updated parsing output of arch-audit\n- Added support for SentinelOne detection\n- Replacing deprecated option -i for xargs\n- Path detection for PostgreSQL improved\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.9 (2023-08-03)\n\n### Changed\n- DBS-1820 - Added newer style format for Mongo authorization setting\n- FILE-6410 - Locations added for plocate\n- SSH-7408 - Only test Compression if sshd version < 7.4\n- Improved fetching timestamp\n- Minor changes such as typos\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.8 (2022-05-17)\n\n### Added\n- MALW-3274 - Detect McAfee VirusScan Command Line Scanner\n- PKGS-7346 Check Alpine Package Keeper (apk)\n- PKGS-7395 Check Alpine upgradeable packages\n- EOL for Alpine Linux 3.14 and 3.15\n\n### Changed\n- AUTH-9408 - Check for pam_faillock as well (replacement for pam_tally2)\n- FILE-7524 - Test enhanced to support symlinks\n- HTTP-6643 - Support ModSecurity version 2 and 3\n- KRNL-5788 - Only run relevant tests and improved logging\n- KRNL-5820 - Additional path for security/limits.conf\n- KRNL-5830 - Check for /var/run/needs_restarting (Slackware)\n- KRNL-5830 - Add a presence check for /boot/vmlinuz\n- PRNT-2308 - Bugfix that prevented test from storing values correctly\n- Extended location of PAM files for AARCH64\n- Some messages in log improved\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.7 (2022-01-18)\n\n### Added\n- MALW-3290 - Show status of malware components\n- OS detection for RHEL 6 and Funtoo Linux\n- Added service manager openrc\n\n### Changed\n- DBS-1804 - Added alias for MariaDB\n- FINT-4316 - Support for newer Ubuntu versions\n- MALW-3280 - Added Trend Micro malware agent\n- NETW-3200 - Allow unknown number of spaces in modprobe blacklists\n- PKGS-7320 - Support for Garuda Linux and arch-audit\n- Several improvements for busybox shell\n- Russian translation of Lynis extended\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.6 (2021-07-22)\n\n### Added\n- OS detection: Artix Linux, macOS Monterey, NethServer, openSUSE MicroOS\n- Check for outdated translation files\n\n### Changed\n- DBS-1826 - Check if PostgreSQL is being used\n- DBS-1828 - Test multiple PostgreSQL configuration file(s)\n- KRNL-5830 - Sort kernels by version instead of modification date\n- PKGS-7410 - Don't show exception for systems using LXC\n- GetHostID function: fallback options added for Linux systems\n- Fix: macOS Big Sur detection\n- Fix: show correct text when egrep is missing\n- Fix: variable name for PostgreSQL\n- German and Spanish translations extended\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.5 (2021-07-02)\n\n### Added\n- OS detection of Arch Linux 32, BunsenLabs Linux, and Rocky Linux\n- CRYP-8006 - Check MemoryOverwriteRequest bit to protect against cold-boot attacks (Linux)\n\n### Changed\n- ACCT-9622 - Corrected typo\n- HRDN-7231 - When calling wc, use the short -l flag instead of --lines (Busybox compatibility)\n- PKGS-7320 - extended to Arch Linux 32\n- Generation of host identifiers (hostid/hostid2) extended\n- Linux host identifiers are now using ip as preferred input source\n- Improved logging in several areas\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.4 (2021-05-11)\n\n### Added\n- ACCT-9670 - Detection of cmd tooling\n- ACCT-9672 - Test cmd configuration file\n- BOOT-5140 - Check for ELILO boot loader presence\n- OS detection of AlmaLinux, Garuda Linux, Manjaro (ARM), and others\n\n### Changed\n- BOOT-5104 - Add service manager detection support for runit\n- FILE-6430 - Report suggestion only when at least one kernel module is not in the blacklist\n- FIRE-4540 - Corrected nftables empy ruleset test\n- LOGG-2138 - Do not check for klogd when metalog is being used\n- TIME-3185 - Improved support for Debian stretch\n- Corrected issue when Lynis is not executed directly from lynis directory\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.3 (2021-01-07)\n\n### Added\n- HRDN-7231 - Check for registered non-native binary formats\n- OS detection of Parrot GNU/Linux\n\n### Changed\n- DBS-1816  - Force test to check only password authentication\n- KRNL-5677 - Support for NetBSD\n- Bugfix: command 'configure settings' did not work as intended\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.2 (2020-12-24)\n\n### Added\n- AUTH-9284 - Scan for locked user accounts in /etc/passwd\n- LOGG-2153 - Loghost configuration\n- TOOL-5130 - Check for active Suricata daemon\n- OS detection of Flatcar, IPFire, Mageia, NixOS, ROSA Linux, SLES (extended), Void Linux, Zorin OS\n- OS detection of OpenIndiana (Hipster and Legacy), Shillix, SmartOS, Tribblix, and others\n- EOL dates for Alpine, macOS, Mageia, OmniosCE, and Solaris 11\n- Support for Solaris svcs (service manager)\n- Enumeration of Solaris services\n\n### Changed\n- ACCT-9626 - Detect sysstat systemd unit\n- AUTH-9230 - Only fail if both SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS are undefined\n- BOOT-5184 - Support for Solaris\n- KRNL-5830 - Improved reboot test by ignoring known bad values\n- KRNL-5830 - Ignore rescue kernel such as on CentOS systems\n- KRNL-5830 - Detection of Alpine Linux kernel\n- NETW-2400 - Compatibility change for hostname check\n- NETW-3012 - Support for Solaris\n- PKGS-7410 - Don't show exception if no kernels were found on the disk\n- TIME-3185 - Supports now checking files at multiple locations (systemd)\n- ParseNginx function: Support include on absolute paths\n- ParseNginx function: Ignore empty included wildcards\n- Set 'RHEL' as OS_NAME for Red Hat Enterprise Linux\n- HostID: Use first e1000 interface and break after match\n- Translations extended and updated\n- Test if pgrep exists before using it\n- Better support for busybox shell\n- Small code enhancements\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.1 (2020-10-05)\n\n### Added\n- Detection of Alpine Linux\n- Detection of CloudLinux\n- Detection of Kali Linux\n- Detection of Linux Mint\n- Detection of macOS Big Sur (11.0)\n- Detection of Pop!_OS\n- Detection of PHP 7.4\n- Malware detection tool: Microsoft Defender ATP\n- New flag: --slow-warning to allow tests more time before showing a warning\n- Test TIME-3185 to check systemd-timesyncd synchronized time\n- rsh host file permissions\n\n### Changed\n- AUTH-9229 - Added option for LOCKED accounts and bugfix for older bash versions\n- BOOT-5122 - Presence check for grub.d added\n- CRYP-7902 - Added support for certificates in DER format\n- CRYP-7931 - Added data to report\n- CRYP-7931 - Redirect errors (e.g. when swap is not encrypted)\n- FILE-6430 - Don't grep nonexistent modprobe.d files\n- FIRE-4535 - Set initial firewall state\n- INSE-8312 - Corrected text on screen\n- KRNL-5728 - Handle zipped kernel configuration correctly\n- KRNL-5830 - Improved version detection for non-symlinked kernel\n- MALW-3280 - Extended detection of BitDefender\n- TIME-3104 - Find more time synchronization commands\n- TIME-3182 - Corrected detection of time peers\n- Fix: hostid generation routine would sometimes show too short IDs\n- Fix: language detection\n- Generic improvements for macOS\n- German translation updated\n- End-of-life database updated\n- Several minor code enhancements\n\n---------------------------------------------------------------------------------\n\n## Lynis 3.0.0 (2020-06-18)\n\nThis is a major release of Lynis and includes several big changes.\nSome of these changes may break your current usage of the tool, so test before\ndeployment!\n\n### Security issues\nThis release resolves two security issues\n* CVE-2020-13882 - Discovered by Sander Bos, code submission by Katarina Durechova\n* CVE-2019-13033 - Discovered by Sander Bos\n\n### Breaking change: Non-interactive by default\nLynis now runs non-interactive by default, to be more in line with the Unix\nphilosophy. So the previously used '--quick' option is now default, and the tool\nwill only wait when using the '--wait' option.\n\n### Breaking change: Deprecated options\n- Option: -c\n- Option: --check-update/--info\n- Option: --dump-options\n- Option: --license-key\n\n### Breaking change: Profile options\nThe format of all profile options are converted (from key:value to key=value).\nYou may have to update the changes you made in your custom.prf.\n\n### Security\nAn important focus area for this release is on security. We added several\nmeasures to further tighten any possible misuse.\n\n## New: DevOps, Forensics, and pentesting mode\nThis release adds initial support to allow defining a specialized type of audit.\nUsing the relevant options, the scan will change base on the intended goal.\n\n### Added\n- Security: test PATH and warn or exit on discovery of dangerous location\n- Security: additional safeguard by testing if common system tools are available\n- Security: test parameters and arguments for presence of control characters\n- Security: filtering out unexpected characters from profiles\n- Security: test if setuid bit is set on Lynis binary\n- New function: DisplayException\n- New function: DisplayWarning\n- New function: Equals\n- New function: GetReportData\n- New function: HasCorrectFilePermissions\n- New function: Readonly\n- New function: SafeFile\n- New function: SafeInput\n- New option: --usecwd - run from the current working directory\n- New profile option: disable-plugin - disables a single plugin\n- New profile option: ssl-certificate-paths-to-ignore - ignore a path\n- New test: AUTH-9229 - check used password hashing methods\n- New test: AUTH-9230 - check group password hashing rounds\n- New test: BOOT-5109 - test presence rEFInd boot loader\n- New test: BOOT-5264 - run systemd-analyze security\n- New test: CRYP-7930 - test for LUKS encryption\n- New test: CRYP-7931 - determine if system uses encrypted swap\n- New test: CRYP-8004 - presence of hardware random number generator\n- New test: CRYP-8005 - presence of software random number generator\n- New test: DBS-1828  - PostgreSQL configuration files\n- New test: FILE-6394 - test virtual memory swappiness (Linux)\n- New test: FINT-4316 - presence of AIDE database and size test\n- New test: FINT-4340 - check dm-integrity status (Linux)\n- New test: FINT-4341 - verify status of dm-verity (Linux)\n- New test: INSE-8314 - test for NIS client\n- New test: INSE-8316 - test for NIS server\n- New test: NETW-2400 - test hostname for valid characters and length\n- New test: NETW-2706 - check DNSSEC (systemd)\n- New test: NETW-3200 - determine enabled network protocols\n- New test: PHP-2382 - detect listen option in PHP (FPM)\n- New test: PROC-3802 - check presence of prelink tooling\n- New test: TIME-3180 - report if ntpctl cannot communicate with OpenNTPD\n- New test: TIME-3181 - check status of OpenNTPD time synchronisation\n- New test: TIME-3182 - check OpenNTPD has working peers\n- New report key: openssh_daemon_running\n- New command: lynis generate systemd-units\n- Sending USR1 signal to Lynis process will show active status\n- Measure timing of tests and report slow tests (10+ seconds)\n- Initial support for Clear Linux OS\n- Initial support for PureOS\n- Support for X Binary Package (xbps)\n- Added end-of-life data for Arch Linux and Debian\n- Detection and end-of-life data added for Amazon Linux\n- Detection of linux-lts on Arch Linux\n- Translations: Russian added\n\n### Changed\n- Function: CheckItem() now returns only exit code (ITEM_FOUND is dropped)\n- Function: IsRunning supports the --user flag to define a related user\n- Function: PackageIsInstalled extended with pacman support\n- Profiles: unused options removed\n- Profiles: message is displayed when old format \"key:value\" is used\n- Binaries: skip pacman when it is the game instead of package manager\n- Security: the 'nounset' (set -u) parameter is now activated by default\n- AUTH-9228 - HP-UX support\n- AUTH-9234 - NetBSD support\n- AUTH-9252 - corrected permission check\n- AUTH-9266 - skip .pam-old files in /etc/pam.d\n- AUTH-9268 - Perform test also on DragonFly, FreeBSD, and NetBSD\n- AUTH-9282 - fix: temporary variable was overwritten\n- AUTH-9408 - added support for pam_tally2 to log failed logins\n- AUTH-9489 - test removed as it is merged with AUTH-9218\n- BANN-7126 - additional words for login banner are accepted\n- BOOT-5122 - check for defined password in all GRUB configuration files\n- CONT-8106 - support newer 'docker info' output\n- CRYP-7902 - optionally check also certificates provided by packages\n- CRYP-8002 - gather kernel entropy on Linux systems\n- FILE-6310 - support for HP-UX\n- FILE-6330 - corrected description\n- FILE-6374 - changed log and allow root location to be changed\n- FILE-6374 - corrected condition to find 'defaults' flag in /etc/fstab\n- FILE-6430 - minor code improvements and show suggestion with more details\n- FILE-7524 - optimized file permissions testing\n- FINT-4328 - corrected text in log\n- FINT-4334 - improved process detection for lfd\n- HOME-9304 - improved selection for normal users\n- HOME-9306 - improved selection for normal users\n- INSE-8050 - added com.apple.ftp-proxy and improved text output\n- INSE-8050 - corrected function call for showing suggestion\n- INSE-8116 - added rsync service\n- INSE-8314 - changed text of suggestion\n- INSE-8318 - test for TFTP client tools\n- INSE-8320 - test for TFTP server tools\n- INSE-8342 - renamed to INSE-8304\n- KRNL-5788 - don't complain about missing /vmlinuz for Raspi\n- KRNL-5820 - extended check to include limits.d directory\n- KRNL-5830 - skip test partially when running non-privileged\n- KRNL-5830 - detect required reboots on Raspbian\n- KRNL-6000 - check more sysctls\n- LOGG-2154 - added support for rsyslog configurations\n- LOGG-2190 - skip mysqld related entries\n- MACF-6234 - SELinux tests extended\n- MAIL-8804 - replaced static strings with translation-aware strings\n- MALW-3280 - Kaspersky detection added\n- MALW-3280 - CrowdStrike falcon-sensor detection added\n- NAME-4402 - check if /etc/hosts exists before performing test\n- NAME-4404 - improved screen and log output\n- NAME-4408 - corrected Report function call\n- NETW-3032 - small rewrite of test and extended with addrwatch\n- PHP-2372 - don't look in the cli configuration files\n- PKGS-7388 - only perform check for Debian/Ubuntu/Mint\n- PKGS-7410 - use multiple package managers when available\n- PKGS-7410 - added support for Zypper to test number of kernels\n- PRNT-2308 - check also for Port and SSLListen statements\n- PROC-3602 - allow different root directory\n- PROC-3612 - show 'Not found' instead of 'OK'\n- PROC-3614 - show 'Not found' instead of 'OK'\n- PROC-3802 - limit to Linux only (prelink package check)\n- SCHD-7702 - removed hardening points\n- SINT-7010 - limit test to only macOS systems\n- SSH-7402 - detect other SSH daemons like dropbear\n- SSH-7406 - strip OpenSSH patch version and remove characters (carriage return)\n- SSH-7408 - changed text in suggestion and report\n- SSH-7408 - added forced-commands-only option\n- SSH-7408 - VerifyReverseMapping removed (deprecated)\n- SSH-7408 - corrected OpenSSH server version check\n- STRG-1840 - renamed to USB-1000\n- STRG-1842 - added default authorized devices and renamed to USB-2000\n- TIME-3104 - use find to discover files in cron directories\n- TOOL-5002 - differentiate between a discovered binary and running process\n- TOOL-5160 - added support for OSSEC agent daemon\n- Perform additional check to ensure pacman package manager is used\n- Use 'pre-release/release' (was: 'dev/final') with 'lynis show release'\n- Use only locations from PATH environment variable, unless it is not defined\n- Show tip to use 'lynis generate hostids' when host IDs are missing\n- The 'show changelog' command works again for newer versions\n- Several code cleanups, simplification of commands, and code standardization\n- Tests using lsof may ignore individual threads (if supported)\n- Corrected end-of-life detection for CentOS 7 and CentOS 8\n- Tests can require detected package manager (--package-manager-required)\n- Do not show tool tips when quiet option is used\n- Improved screen output in several tests\n- Extended output of 'lynis update info'\n- Improved support for NetBSD\n- Test if profiles are readable\n- systemd service file adjusted\n- bash completion script extended\n- Updated man page\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.7.5 (2019-06-24)\n\n### Added\n- Danish translation\n- Slackware end-of-life information\n- Detect BSD-style (rc.d) init in Linux systems\n- Detection of Bro and Suricata (IDS)\n\n### Changed\n- Corrected end-of-life entries for CentOS 5 and 6\n- AUTH-9204 - change name to check in /etc/passwd file for QNAP devices\n- AUTH-9268 - AIX enhancement to use correct find statement\n- FILE-6310 - Filter on correct field for AIX\n- NETW-3012 - set ss command as preferred option for Linux and changed output format\n- List of PHP ini file locations has been extended\n- Removed several pieces of the code as part of cleanup and code health\n- Extended help\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.7.4 (2019-04-21)\n\nThis is a bigger release than usual, including several new tests created by\nCapashenn (GitHub). It is a coincidence that it is released exactly one month\nafter the previous version and on Easter. No easter eggs, only improvements!\n\n### Added\n- FILE-6324 - Discover XFS mount points\n- INSE-8000 - Installed inetd package\n- INSE-8100 - Installed xinetd package\n- INSE-8102 - Status of xinet daemon\n- INSE-8104 - xinetd configuration file\n- INSE-8106 - xinetd configuration for inactive daemon\n- INSE-8200 - Usage of TCP wrappers\n- INSE-8300 - Presence of rsh client\n- INSE-8302 - Presence of rsh server\n- Detect equery binary detection\n- New 'generate' command\n\n### Changed\n- AUTH-9278 - Test LDAP in all PAM components on Red Hat and other systems\n- PKGS-7410 - Add support for DPKG-based systems to gather installed kernel packages\n- PKGS-7420 - Detect toolkit to automatically download and apply upgrades\n- PKGS-7328 - Added global Zypper option --non-interactive\n- PKGS-7330 - Added global Zypper option --non-interactive\n- PKGS-7386 - Only show warning when vulnerable packages were discovered\n- PKGS-7392 - Skip test for Zypper-based systems\n- Minor changes to improve text output, test descriptions, and logging\n- Changed CentOS identifiers in end-of-life database\n- AIX enhancement for IsRunning function\n- Extended PackageIsInstalled function\n- Improve text output on AIX systems\n- Corrected lsvg binary detection\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.7.3 (2019-03-21)\n\n### Added\n- Detection for Lynis being scheduled (e.g. cronjob)\n\n### Changed\n- HTTP-6624 - Improved logging for test\n- KRNL-5820 - Changed color for default fs.suid_dumpable value\n- LOGG-2154 - Adjusted test to search in configuration file correctly\n- NETW-3015 - Added support for ip binary\n- SQD-3610  - Description of test changed\n- SQD-3613  - Corrected description in code\n- SSH-7408  - Increased values for MaxAuthRetries\n- Improvements to allow tailored tool tips in future\n- Corrected detection of blkid binary\n- Minor textual changes and cleanups\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.7.2 (2019-03-07)\n\n### Added\n- AUTH-9409 - Support for doas (OpenBSD)\n- AUTH-9410 - Test file permissions of doas configuration\n- BOOT-5117 - Support for systemd-boot boot loader added\n- BOOT-5177 -  Simplify service filter and allow multiple dots in service names\n- BOOT-5262 - Check OpenBSD boot daemons\n- BOOT-5263 - Test permissions for boot files and scripts\n- Support for end-of-life detection of the operating system\n- New 'lynis show eol' command\n- Korean translation\n\n### Changed\n- AUTH-9252 - Adds support for files in sudoers.d\n- AUTH-9252 - Test extended to check file and directory ownership\n- BOOT-5122 - Use NONE instead of WARNING if no password is set\n- FIRE-4540 - Modify test to better measure rules\n- KRNL-5788 - Resolve false positive warning on missing /vmlinuz\n- NETW-2704 - Ignore inline comments in /etc/resolv.conf\n- PKGS-7388 - Improve detection for security archive\n- RPi/Raspian path to PAM_FILE_LOCATIONS\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.7.1 (2019-01-30)\n\n### Added\n- Support for macOS Mojave\n- Translation: Slovak\n\n### Changed\n- AUTH-9282 - Improve support for Red Hat and clones\n- FIRE-4534 - Additional support for Hands Off!, LuLu, and Radio Silence\n- LOGG-2190 - Added MariaDB filter for deleted files (tested on CentOS)\n- SHLL-6230 - Add /etc/bash.bashrc.local to umask check\n- Removed shift statement that did not work on all operating systems\n- Minor cleanups and enhancements\n- Small improvements to logging\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.7.0 (2018-10-26)\n\n### Added\n- MACF-6240 - Detection of TOMOYO binary\n- MACF-6242 - Status of TOMOYO framework\n- SSH-7406  - OpenSSH server version detection\n- TOOL-5160 - Check active OSSEC analysis daemon\n\n### Changed\n- Changed several warning labels on screen\n- AUTH-9308 - More generic sulogin for systemd rescue.service\n- OS detection now ignores quotes for getting the OS ID.\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.6.9 (2018-09-19)\n\n### Changed\n- Man page has been updated\n- Command 'lynis show options' provides up-to-date list\n- Option '--dump-options' is deprecated\n- Several options and commands have been extended with more examples\n- OS detection now supports openSUSE specific distribution names\n- Changed command output when using 'lynis audit system remote'\n- DBS-1882  - added /usr/local/redis/etc path and QNAP support\n- PKGS-7322 - updated solution text\n- KRNL-5788 - ignore exception when no vmlinuz file was discovered\n- TIME-3104 - extended logging for test\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.6.8 (2018-08-23)\n\n### Changed\n- BOOT-5104 - improved parsing of boot parameters to init process\n- PHP-2372  - test all PHP files for expose_php and improved logging\n- Alpine Linux detection for Docker audit\n- Docker check now tests also for CMD, ENTRYPOINT, and USER configuration\n- Improved display in Docker output for showing which keys are used for signing\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.6.7 (2018-08-09)\n\n### Changed\n- BOOT-5104 - Added busybox as a service manager\n- KRNL-5677 - Limit PAE and no-execute test to AMD64 hardware only\n- LOGG-2190 - Ignore /dev/zero and /dev/[aio] as deleted files\n- SSH-7408  - Changed classification of SSH root login with keys\n- Docker scan uses new format for maintainer value\n- New URL structure on CISOfy website implemented for Lynis controls\n\n---------------------------------------------------------------------------------\n\n## Lynis 2.6.6 (2018-07-06)\n\n### Changed\n* New format of changelog (https://keepachangelog.com/en/1.0.0/)\n* KRNL-5830 - Improved log text about running kernel version\n\n### Fixed\n* Under some condition no hostid2 value was reported\n* Solved 'extra operand' issue with tr command\n\n---------------------------------------------------------------------------------\n\nLynis 2.6.5 (2018-06-26)\n\nTests:\n------\n\n* [MAIL-8804] - Exim configuration test\n* [NETW-2704] - Use FQDN to test status of a nameserver instead of own IP address\n* [SSH-7402]  - Improved test to allow configurations with a Match block\n\n---------------------------------------------------------------------------------\n\nLynis 2.6.4 (2018-05-02)\n\nChanges:\n--------\n* Several contributions merged, including grammar improvements\n* Initial support for Ubuntu 18.04 LTS\n* Small enhancements for usage\n\nTests:\n------\n* [AUTH-9308] - Made 'sulogin' more generic for systemd rescue shell\n* [DNS-1600]  - Initial work on DNSSEC validation testing\n* [NETW-2704] - Added support for local resolver 127.0.0.53\n* [PHP-2379]  - Suhosin test disabled\n* [SSH-7408]  - Removed 'DELAYED' from OpenSSH Compression setting\n* [TIME-3160] - Improvements to detect step-tickers file and entries\n\n---------------------------------------------------------------------------------\n\nLynis 2.6.3 (2018-03-07)\n\nChanges:\n--------\n* Change in routine for host identifiers\n\nTests:\n------\n* [CRYP-7902] - Do prevalidation for certificates before testing them\n* [HRDN-7222] - Enhanced compiler permission test\n* [NAME-4402] - Improved test to filter out empty lines\n* [PKGS-7384] - Changes to detect yum-utils package and related tooling\n\nPlugins:\n--------\n* [PLGN-2680] - cron file permissions\n\n---------------------------------------------------------------------------------\n\nLynis 2.6.2 (2018-02-13)\n\nChanges:\n--------\n* Bugfix for Arch Linux (binary detection)\n* Textual changes for several tests\n* Update of tests database\n\n---------------------------------------------------------------------------------\n\nLynis 2.6.1 (2018-01-26)\n\nChanges:\n--------\n* Tests can have more than 1 required OS (e.g. Linux OR NetBSD)\n* Added 'system-groups' option to profile (Enterprise users)\n* Overhaul of default profile and migrate to new style (setting=value)\n* Show warning if old profile options are used\n* Improved detection of binaries\n* New group 'usb' for tests related to USB devices\n\nTests:\n------\n* [FILE-6363] - New test for /var/tmp (sticky bit)\n* [MAIL-8802] - Added exim4 process name to improve detection of Exim\n* [NETW-3030] - Changed name of dhcp client name process and added udhcpc\n* [SSH-7408]  - Restored UsePrivilegeSeparation\n* [TIME-3170] - Added chrony configuration file for NetBSD\n\n---------------------------------------------------------------------------------\n\nLynis 2.6.0 (2018-01-18)\n\nChanges:\n--------\n* Binary paths are now sorted\n* Greek language added\n* systemd detection improved\n* VirtualBox detection extended\n* Several code enhancements\n\nTests:\n------\n* [PHP-2379]  - Small enhancement to resolve error on screen in some cases\n* [MALW-3280] - Improved detection for BitDefender tooling\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.9 (2018-01-12)\n\nChanges:\n--------\n* Don't show upgrade notice when being quiet/silent\n* Added --noplugins as an alias to skip execution of plugins\n* Use PATH variable for path detection, with predefined list as a backup\n\nTests:\n------\n* [KRNL-6000] - Multiple values are now allowed per sysctl key\n* [KRNL-6000] - Individual tests can be skipped (skip-test=KRNL-6000:<sysctl-key>)\n* [KRNL-6000] - Solution text has been added\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.8 (2017-12-28)\n\nChanges:\n--------\n* Check for empty files improved on several locations\n* New allow-auto-purge setting in profile for short-lived systems\n* Additional checks for log and report file\n* Changes to support time synchronization in old and newer systemd releases\n* Enhanced output for systems other than Linux\n\nPlugins:\n--------\n* New class (hardware) added and enabled in default profile\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.7 (2017-10-29)\n\nChanges:\n--------\n* Update of Portuguese translation\n* Added --silent as alias for --quiet\n* Reduced screen output when running non-privileged\n* IsRunning function now allows full name process match\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.6 (2017-10-27)\n\nChanges:\n--------\n* Added additional keywords for banners\n* DirectAdmin extensions\n* Enhancements to process detection\n* Spanish translation extended\n* Extended HP-UX support\n* Only show relevant messages in report\n\nTests:\n------\n* [NETW-2705] - Allow local resolvers to bypass requirement for 2+ name servers\n* [SSH-7408]  - Define default 'delayed' compression as a sane value for SSH tests\n* [SHLL-6220] - Improved detection of shell settings\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.5 (2017-09-07)\n\nChanges:\n--------\n* Minor release to solve errors on screen\n\nTests:\n------\n* CRYP-7902 - certificate validation changed\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.4 (2017-09-05)\n\nChanges:\n--------\n* Improve systemd detection\n* Detect Linux Mint version\n* Older versions of Mac OS X are detected as well\n* Norwegian translation added\n* PAM plugin extended\n\nTests:\n------\n* CRYP-7902 - certificate validation changed\n* FIRE-4508 - Improved screen output\n* PKGS-7380 - NetBSD vulnerability detection adjusted\n* TOOL-5002 - Improved detection of Ansible directories and files\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.3 (2017-08-17)\n\nChanges:\n--------\n* DirectAdmin location added\n* Small adjustments to text\n* Enhanced detection for LXC and LXC\n* Added /opt/apache as a target location\n* Default log directory set for HP-UX\n* Screen output improvements\n\nTests:\n------\n* CRYP-7902 - Prevent test from showing error on screen\n* FILE-6310 - Detection of mount point now match exact name\n* HRDN-7230 - Show single line when no malware scanner was detected\n* NETW-3006 - Updated detection of MAC addresses on Linux\n* PKGS-2379 - Improvement for OpenBSD usage of PHP suhosin\n* TOOL-5002 - Detection capabilities for Ansible added\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.2 (2017-07-10)\n\nChanges:\n--------\n- Support for PHP on CloudLinux\n- Check for presence of locale binary\n- Suhosin detection improvements\n- Generic code improvements\n- Changed 'lynis audit system remote' routine\n- Support for macOS High Sierra\n- French translation updated\n\nLynis Enterprise:\n-----------------\n- Allow 'tags' and 'system-customer-name' to be specified via Lynis client\n\nTests:\n------\n* CONT-8102 - Check for dockerd instead of docker -d\n* FIRE-4594 - Check for presence Advanced Policy Firewall (APF)\n* PKGS-2379 - New test for PHP suhosin extension status\n* PKGS-7370 - Only use debsums on Debian\n* KRNL-6000 - Added kernel.dmesg_restrict testing\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.1 (2017-05-31)\n\nChanges:\n--------\n- Hebrew translation by Dolev Farhi\n- Improved detection of SSL certificate files\n- Minor changes to improve logging and results\n\nTests:\n------\n* BOOT-5104 - Added support for macOS\n* FIRE-4524 - Determine if CSF is in testing mode\n* HTTP-6716 - Improved log message\n\n---------------------------------------------------------------------------------\n\nLynis 2.5.0 (2017-05-03)\n\nDuring the development of this release, the project got informed about a flaw\nthat possibly could be abused by a local attacker. Even with the small risk of\nsuccess, upgrading is highly recommended. See details on\n[CVE-2017-8108](https://cisofy.com/security/cve/cve-2017-8108/)\n\nThis release is a special maintenance release with focus on cleaning up the code\nfor readability and future expansion.\n\nChanges:\n--------\n* Use ROOTDIR variable instead of fixed paths\n* Introduction of IsEmpty and HasData functions for readability of code\n* Renamed some variables to better indicate their purpose (counting, data type)\n* Removal of unused code and comments\n* Deleted unused tests from database file\n* Correct levels of indentation\n* Support for older mac OS X versions (Lion and Mountain Lion)\n* Initialized variables for more binaries\n* Additional sysctls are tested\n\nTests:\n------\n* MALW-3280 - Extended test with Symantec components\n* PKGS-7332 - Detection of macOS ports tool and installed packages\n* TOOL-5120 - Snort detection\n* TOOL-5122 - Snort configuration file\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.8 (2017-03-29)\n\nChanges:\n* More PHP paths added\n* Minor changes to text\n* Show atomic test in report\n\nTests:\n------\n* MAIL-8820 - New Postfix configuration check\n* TOOL-5002 - Extended Puppet detection\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.7 (2017-03-22)\n\nChanges:\n* Minor code cleanups\n\nTests:\n------\n* BANN-7126 - Added more words to test for\n* CUPS-2308 - Improve logging for CUPS configuration test, removed exception handler\n* HTTP-6641 - Support detection for Apache module mod_reqtimeout\n* PKGS-7388 - Minor change to detect security repositories\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.6 (2017-03-15)\n\nChanges:\n--------\n* Added FileInstalledByPackage function (dpkg and rpm supported)\n* Mark Arch Linux version as rolling release (instead of unknown)\n* Support for Manjaro Linux\n* Escape files when testing if they are readable\n* Code cleanups\n\nTests:\n------\n* CRYP-7902 - Test more certificates names, but only if they are not part of a package\n* FILE-7524 - Reduce standard screen output for file permissions check\n* MALW-3280 - Added Avira detection as a malware scanner\n* NAME-4018 - Only perform name services test when resolv.conf file exists\n* PKGS-7387 - Check all repositories if they use GPG signing\n* SCHD-7704 - Permission checks\n* TIME-3104 - Check permissions before open files\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.5 (2017-03-09)\n\nChanges:\n--------\n* Allow host alias to be specified in profile\n* Code readability enhancements\n* Solaris support has been improved\n\nTests:\n------\n* AUTH-9328 - Add missing 0027 and 0077 umasks\n* BOOT-5104 - Add initsplash and minor code enhancements\n* DBS-1882  - Include Redis configuration file\n* FIRE-4502 - Improved detection for iptables modules when using OpenVZ\n* PKGS-7381 - Enhanced package audit for FreeBSD\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.4 (2017-03-01)\n\nChanges:\n--------\n* Fix for upload function to be used from profile\n* Reduce screen output for mail section, unless --verbose is used\n* Code cleanups and removed 'update release' command\n\nTests:\n------\n* AUTH-9308 - Improved test for sulogin string (Debian systems)\n* FILE-6372 - Properly deal with comment on lines in /etc/fstab\n* MAIL-8817 - New test to check Postfix configuration for errors\n* SSH-7408  - Corrected SSH check\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.3 (2017-02-22)\n\nChanges:\n--------\n* Colored output can now be tuned with profile (colors=yes/no)\n* Allow data upload to be set as a profile option\n\nTests:\n------\n* AUTH-9308 - Improved test for sulogin string\n* MAIL-8818 - Test if Linux version is known before comparing in Postfix banner\n* TIME-3116 - Skip stratum 16 items for time pools\n* TIME-3148 - New test to detect TZ variable\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.2 (2017-02-15)\n\nChanges:\n--------\n* Properly detect SSH daemon version\n\nTests:\n------\n* AUTH-9208 - Removed double logging\n* AUTH-9222 - Improve logging for double groups\n* AUTH-9226 - Improve logging for double groups\n* BOOT-5177 - Sort systemctl unit files to make them unique\n* DBS-1818  - New test to detect MongoDB\n* DBS-1820  - New test for MongoDB authentication\n* FIRE-4512 - Lowered minimum number of iptables firewall rules\n* FIRE-4586 - Fix applied when searching for \"-j LOG\"\n* HRDN-7222 - Changed reporting key of world executable compilers\n* SSH-7408  - Added filtering for PermitRootLogin (prohibit-password, OpenSSH 7.0)\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.1 (2017-02-09)\n\nChanges:\n--------\n* Generic code improvements\n* Improved the update check and display\n* Finish, Portuguese, and Turkish translation\n* Extended support and tests for DragonFlyBSD\n* Option to configure hostid and hostid2 in profile\n* Support for Trend Micro and Cylance (macOS)\n* Remove comments at end of nginx configuration\n* Used machine ID to create host ID when no SSH keys are available\n* Added detection of iptables-save to binaries\n\nTests:\n------\n* FIRE-4586 - Check logging for firewall components\n* KRNL-5788 - Remove exception and style improvements\n* KRNL-5830 - Improved logging\n\n---------------------------------------------------------------------------------\n\nLynis 2.4.0 (2016-10-27)\n\nExactly one month after previous release, the Lynis project is proud to announce\na new release. This release had the specific focus to improve support for macOS\nusers. Thanks to testers and contributors to make this possible.\n\nNew:\n----\n* New group \"system integrity\" added\n* Support for clamconf utility\n* Chinese translation (language=cn)\n* New command \"upload-only\" to upload just the data instead of a full audit\n* Enhanced support for macOS, including HostID2 generation for macOS\n* Support for CoreOS\n* Detection for pkg binary (FreeBSD)\n* New command: lynis show hostids (show host ID)\n* New command: lynis show environment (hardware, VM, or container type)\n* New command: lynis show os (show operating system details)\n\nChanges:\n--------\n* Several new sysctl values have been added to the default profile\n* Existing tests have been enhanced to support macOS\n\nTests:\n------\n* AUTH-9234 - Support for macOS user gathering\n* BOOT-5139 - Support for machine roles in LILO test\n* BOOT-5202 - Improve uptime detection for macOS and others\n* FIRE-4518 - Improve pf detection and mark as root-only test\n* FIRE-4530 - Don't show error on screen for missing IPFW sysctl key\n* FIRE-4534 - Check Little Snitch on macOS\n* INSE-8050 - Test for insecure services on macOS\n* MACF-6208 - Allow non-privileged execution and filter permission issues\n* MALW-3280 - Detection for Avast and Bitdefender daemon on macOS\n* NETW-3004 - Support for macOS\n* PKGS-7381 - Improve test for pkg audit on FreeBSD\n* TIME-3104 - Chrony support extended\n\nPlugins (community and commercial):\n-----------------------------------\n* PLGN-1430 - Gather installed software packages for macOS\n* PLGN-4602 - Support for Clam definition check on macOS\n\n---------------------------------------------------------------------------------\n\nLynis 2.3.4 (2016-09-27)\n\nChanges:\n--------\n* Skip update message when using the 'show' helper\n* Instead of opening the log file, you can now use 'lynis show details' followed\n  by the test ID. It will show the relevant section.\n* Several tests have extended log details\n* Many style improvements as part of ongoing refactoring of the code\n* Detection of nftables improved\n* Replaced cut, sed, tr and others commands with binary variable (for forensics\n  and future intrusion checking capabilities)\n* Swedish translation provided by Peter Carlsson\n* Support for arch-audit to scan for presence of vulnerable packages on Arch Linux\n* OS detection improved\n\nTests:\n------\n* CONT-8107 - New test checking number of Docker containers\n* CRYP-7902 - Gather more details regarding certificates\n* DBS-1816  - Define skip reason\n* FILE-6344 - Adjusted /proc test for hidepid option\n* FILE-6362 - Removed warning and add skip reason\n* FIRE-4520 - Change test to use detected binary\n* FIRE-4520 - New test to check for empty nftables ruleset\n* KRNL-5820 - Corrected function and style improvements\n* LOGG-2146 - Textual change\n* NAME-4408 - Check localhost to IP mapping\n* PKGS-7320 - Test for arch-audit tool\n* PKGS-7322 - Check vulnerable packages on Arch Linux\n* PKGS-7381 - Extended vulnerable package detection for FreeBSD\n* TIME-3104 - timedatectl test now detects NTP synchronization properly\n\n\n---------------------------------------------------------------------------------\n\nLynis 2.3.3 (2016-08-23)\n\n\nUpgrade note\n------------\nCustomized profiles that included sysctl settings need to be altered. See\ndefault.prf for the correct format of the lines.\n\n\nAdditions\n---------\n* OpenStack detection\n* Option to disable automatic refresh of software repository\n\n\nLanguages\n---------\n* Japanese translation added, contributed by Yukio Takahara\n\n\nFixes\n-----\n* Some tests did not show a warning text\n* Typo in man page for tests-from-group\n\n\nParameters\n----------\n* New --bin-dirs to define binary directories to scan\n* New option --root-dir to specify a different file system to scan\n\n\nNginx\n-----\n* Rewrite of configuration parsing\n\n\nPHP\n---\n* Support for PHP 5.6\n\n\nRedis\n-----\n* Redis test to detect configuration files\n* Test Redis configuration for several best practices\n* Perform permission check on Redis configuration files\n\n\nExperimental features (in development)\n--------------------------------------\n* --bin-dirs - set what directories should be scanned for binaries\n* --root-dir - define the root of the file system, to allow forensics\n\n\nSettings\n--------\n* Many settings have a new alias (with dashes instead underscores)\n* New setting 'show-report-solution' to show solution in report\n\n\nFunctions\n---------\n* ExitFatal can now exit program with optional text\n* IsNotebook can detect if system is a notebook (or not)\n* ShowSymlinkPath and FileIsReadable test for at least one argument\n* StoreNginxSettings will save parsed nginx configuration\n\n\nTests\n-----\n* BOOT-5108 - Support for Syslinux bootloader\n* DBS-1882  - Redis configuration detection\n* DBS-1884  - Redis 'requirepass' check\n* DBS-1886  - Redis 'rename-command CONFIG' check\n* DBS-1888  - Redis 'bind localhost' check\n* FILE-6374 - Improved logging\n* KRNL-5830 - Improved logging for detected Linux kernels\n* KRNL-6000 - Support for multiple profiles and new format style\n* LOGG-2190 - Ignore MySQL files in /tmp from early MySQL 5.x releases\n* LOGG-2192 - New test to check opened log files that are empty\n\nLynis Enterprise integration\n----------------------------\n* Tag 'redis-server' is added for systems running Redis\n\n\n---------------------------------------------------------------------------------\n\nLynis 2.3.2 (2016-08-09)\n\n\nCategories and Groups\n---------------------\nTests are now grouped by their focus area and named 'groups' accordingly.\nBesides groups, each test will belong to a category (performance, privacy, or\nsecurity).\n\nCommands: lynis show categories, lynis show groups\nOptions: --tests-from-category, --tests-from-group\n\nNote: You might need to change your scripts if you previously defined the group\nof tests to scan.\n\n\nDevelopment\n\n-----------\nA new 'strict' option is available in the profiles and by default enabled for\nthe initialization phases of Lynis. It will perform a strict code check for the\ntests, to detect any uninitialized variables, improving code quality.\n\n\nHelpers\n-------\nWith 'lynis update check' you can now check for updates. This is the preferred\nnew method.\n\nThe command 'lynis show changelog' allows reviewing the changes. Optionally a\nrelease can be specified as additional argument.\n\n\nLanguages\n---------\nInitial translation for German has been contributed by Kai Raven. The Italian\ntranslation by Stefano Marty (stefanomarty). Hungarian translation by Zoltan\nPaldi (paldiz)\n\n\nProfiles\n--------\nParsing of the profiles has been improved, which prevented some settings from\noverriding default settings.\n\nTests\n------\n* AUTH-9212 - Added prerequisite to log\n* AUTH-9216 - Simplified test and make it more efficient\n* AUTH-9218 - Clean ups and improve readability\n* AUTH-9226 - Style, text, and removed warning\n* AUTH-9228 - Provide just a suggestion instead of warning\n* AUTH-9268 - Improve test for readability\n* AUTH-9328 - Test /etc/profile.d for umask setting\n* AUTH-9406 - Readability and code style changes\n* CONT-8102 - Determine if all Docker tests should be performed\n* DBS-1880  - Initial support for Redis server\n* HTTP-6720 - Readability improvement of test\n* KRNL-5830 - Readability and style improvements, ignore rescue images\n* MAIL-8818 - Style and refactoring\n* PHP-2211  - Readability improvement and code style changes\n* PHP-2374  - Changed text and cleanups\n* PHP-2376  - Log result to log file instead of report\n* PKGS-7383 - Simplified test\n* PKGS-7388 - Style and readability improvements\n* TIME-3106 - Corrected string to test for status\n* TOOL-5102 - Split of fail2ban tests\n* TOOL-5104 - Test for enabled fail2ban jails\n\n\nLanguages\n---------\nTranslation of Spanish (es) added\nProper display of text strings when accented characters are used\nMore text strings added\n\n\nGeneral\n-------\n* Added bold and header as new colors\n* Changed header and footer of screen output\n* Allow atomic tests to be skipped (e.g. SSH-7408)\n* Extended tests database with category (lynis show tests)\n* By default Lynis will now run in 'quick mode' and not break after each\nsection. You can get this behavior by adding the --wait option.\n\n\nFunctions\n---------\n* RemoveColors - New test to clear colors\n* DisplayError - Display error on screen in uniform format and colors\n                 Use an optional exit code to quit the program\n* SkipAtomicTest - This function is now properly working with lowercase strings\n\n\nWebsite\n-------\nSeveral controls on the website are added or updated, including:\n* FILE-6344\n* FINT-4315\n* FINT-4402\n* HTTP-6714\n* MACF-6234\n* NAME-4018\n* NAME-4402\n* PHP-2374\n* PROC-3612\n* TIME-3106\n\n---------------------------------------------------------------------------------\n\n\nLynis 2.3.1 (2016-07-14)\n-----------------------------------------------\n\nThis is a minor patch to improve upon findings in version 2.3.0.\n\nChanges:\n- Convert all skipped tests to uppercase\n- Only add license key when it is defined\n- Updated French translation\n- Exclude custom.prf from tarball (download via website)\n\n\n--------------------------------------------------------------\n\n\nLynis 2.3.0 (2016-07-13)\n-----------------------------------------------\n\nWe are excited to announce this major release of auditing tool Lynis. Several big\nchanges have been made to core functions of Lynis. These changes are the next of\nsimplification improvements we made. There is a risk of breaking your existing\nconfiguration. See the tips below to upgrade.\n\nThis release will soon also be available in our software repository. For more\ndetails see https://packages.cisofy.com to install and upgrade Lynis.\n\n\nUpgrade tips\n============\n\nDefault profile and custom profiles:\nSettings of multiple profiles can now be merged. Instead of making changes to\ndefault.prf, copy your changes to custom.prf. Use 'lynis show profiles' to show\nany detected profiles. Only include your changes in custom.prf, to keep the\nconfiguration clean and tidy. They will then overwrite the defaults. Use\n'lynis show settings' to see if they are applied.\n\nCheck your cron jobs:\nWhen using --quiet, the output will be really quiet now. Use --show-warnings-only\nif you still want to see the warnings. Lynis will now exit with error 0, even\nwhen warnings have been found. Use option error-on-warnings=yes (custom.prf) to\nexit with code 78 when it has any warnings.\n\n\nDetails\n=======\n\nAnsible\n-------\nNew Ansible examples for deployment: https://github.com/CISOfy/lynis-ansible\n\n\nDatabases\n---------\nLynis will check also for DB2 instances and report the status.\n\n\nDeveloper Mode\n--------------\nWith this release the developer mode is introduced. It can be activated with the\n--developer option, or developer-mode=yes in profile. In development mode, some\ndetails are displayed on screen, to help testing of existing or new tests.\n\nTo get easy access, a new profile has been added (developer.prf).\n\nExamples:\nlynis audit system --profile developer.prf\nlynis audit system --developer\n\nA new software development kit (SDK) for Lynis is available on GitHub. This will\nhelp contributors and developers to test software quality, including linting and\nrunning unit tests. The devkit also supports building DEB and RPM files for easy\ndeployment. The repository can be found on https://github.com/CISOfy/lynis-sdk\n\n\nDocumentation\n-------------\nTemplate files have been updated to provide better examples on how to create\ncustom tests and plugins.\n\nTo simplify the usage of Lynis, a new helper utility has been added: show.\nThis helper will show help, or values (e.g. version, plugin directories, etc).\nSome examples include: lynis show options, lynis show commands, lynis show\nversion, etc. See lynis show for all available details.\n\n\nFile Systems\n------------\nThe XFS file system detection has been added. Mount points /dev/shm and /var/tmp\nare now checked for their options. Comparison of the mount options has been\nimproved. A new test has been added to check if /var/tmp has been bound to /tmp.\n\n\nLanguage Support\n----------------\nLynis now supports language translations, with the language profile option.\nInitial languages: Dutch (nl), English (en), French (fr).\n\nYou can help by translating the language files in the db directory.\n\n\nMac OS X Improvements\n---------------------\nPackage manager Brew has been added\n\n\nnginx\n-----\nShow suggestion when weak protocol is used, like SSLv2 or SSLv3. The protocols\nare now also parsed and stored as details in the report file.\n\n\nPackages\n--------\nSystems running CentOS, Debian, openSUSE, RHEL, Ubuntu and others, may now use\nour own software repository: https://packages.cisofy.com\n\nPerformance\n-----------\nSeveral performance improvements have been implemented. This includes rewriting\ntests to invoke less commands and enhanced hardware detection at the beginning.\n\n\nPlugins\n-------\nYou can set the plugin directory now also via a profile. First match wins.\nPriority: 1) argument, 2) profile, 3) default\n\n--plugindir is now an alias for --plugin-dir\n\n\nProfiles\n--------\nLynis now support multiple profiles. By using a file 'custom.prf', it allows to\ninherit values first from default.prf, then merge it with custom.prf.\n\nSeveral tests have been altered to support multiple profiles.\n\nNew profile options:\n  quick=yes|no (similar to --quick)\n  developer (see Developer section)\n  check-value\n\n\nRemote scanning\n---------------\nAlthough Lynis is a aimed on running on local hosts, there is still an ongoing\ndemand for running remote scans. With 'lynis audit system remote' tips are now\nprovides to perform such a scan via SSH.\n\n\nSoftware\n--------\nZypper calls are now marked with a non-interactive flag to prevent it waiting for\nany interactive input.\n\n\nSolaris\n-------\nImprove execution for Solaris systems.\n\n\nSSH\n---\nThe configuration of SSH is now parsed from the SSH daemon directly. This enables\nhandling with new defaults more easily, as OpenSSH sometimes introduces new keys,\nor change their default value between versions.\n\n\nSystemd\n-------\nAdded support for detecting systemd and reporting it as a service manager. The\nsystemd plugin has been released as a community plugin.\n\n\nUploads\n-------\nSolved a bug which added the proxy configuration twice.\n\nProfile options: upload-tool and upload-tool-arguments\n\n\nGeneral Improvements\n--------------------\nThe screen output has been improved, to show more meaningful things when some\nparameters are missing. Several old variables and lines have been cleaned up.\n\nThe Display function now allows the --debug flag. This helps in showing some\nlines on screen, which would normally be hidden (e.g. items not found or\nmatched).\n\nLogging has been improved in different areas, like cleaning up and add more\nrelevant messages where needed.\n\nThe interface colors have been changed, to make it more obvious how the software\ncan be used. Also the wait line between categories have been altered, to properly\ndisplay on systems with a white background.\n\nWhen no auditor name has been specified, it will say that instead of unknown.\n\nFunctions file has been cleaned up, including adding developer debug information\nwhen old functions are still be used. Later on these functions will be deleted,\nand therefore placed at the bottom.\n\n\nProgram Options\n---------------\n* --developer           - Enable developer mode\n* --verbose             - Show more details on screen, reduce in normal mode\n* --show-warnings-only  - Only show warnings on screen\n* --skip-plugins        - Disable running any plugins (alias: --no-plugins)\n* --quiet               - Changed: become really quiet\n* --config              - Removed: use 'lynis show profiles' instead\n\n\nFunctions\n---------\n* AddSetting            - New function to store settings (lynis show settings)\n* ContainsString        - New function to search for a string in another one\n* Display               - Added --debug, showing details on screen in debug mode\n                        - Reset indentation for lines which are too long\n* DisplayToolTip        - New function to display tooltips\n* IsDebug               - Check for usage of --debug\n* IsDeveloperMode       - Status for development and debugging (--developer)\n* IsDeveloperVersion    - Check if release is still under development\n* IsRunning             - Added return state\n* IsVerbose             - Check for usage of --verbose\n* IsOwnedByRoot         - Check ownership of files and directories\n* IsWorldWritable       - Improved test with additional details\n* PortIsListening       - Check if a service it listening to a specified port\n* SkipAtomicTest        - Allow smaller tests to be skipped (e.g. SSH-7408)\n\n\nTests\n-----\n* AUTH-9234 - Test for minimal UID in /etc/login.defs when available\n* AUTH-9254 - Allow allow root to use this test, due to permissions\n* AUTH-9262 - Restructure of test, support for pwquality PAM\n* AUTH-9288 - Only check for accounts which have a maximum password age set\n* AUTH-9308 - Check for systemd targets\n* BANN-7119 - /etc/motd test disabled\n* BANN-7122 - /motd content test disabled\n* BOOT-5122 - Extended GRUB password check\n* BOOT-5184 - Improve file permissions check for CentOS 7 machines\n* DBS-1860  - Check for status of DB2\n* CRYP-7902 - Improved logging\n* FILE-6354 - Restrict searching in /tmp to mount point only\n* FILE-6372 - Properly checking for /etc/fstab now, ignore comments\n* FILE-6374 - Added /dev/shm and /var/tmp\n* FILE-6374 - New test for /var/tmp\n* FILE-6430 - New test for detecting specific filesystems\n* FILE-7524 - Support for multiple profiles\n* HTTP-6632 - Fix for proper detection of Apache modules\n* HTTP-6642 - Test disabled\n* HTTP-6710 - Trigger suggestion when weak protocols SSLv2/SSLv3 are used\n* KRNL-5788 - Support for kernel with grsecurity patches (linux-image-grsec)\n* KRNL-5820 - Improved logging for test\n* KRNL-6000 - Allow multiple profiles to be used, store more details\n* LOGG-2190 - Improvements for Fail2Ban and cron-related files\n* NETW-3014 - Support for multiple profiles\n* PKGS-7303 - Added Brew package manager\n* PKGS-7354 - Test for DNF repoquery plugin before using it\n* PKGS-7381 - Check for vuln.xml file\n* PRNT-2306 - Check if files are readable before parsing them\n* PROC-3612 - Removed wchan output to prevent grsecurity issues\n* SCHD-7702 - Test for running cron daemon\n* SCHD-7704 - Test ownership of cronjob files\n* SSH-7408  - Show weak configurations of SSH on screen as a suggestion\n* TOOL-5102 - Test for Fail2ban tooling\n* TOOL-5190 - Test for intrusion detection or prevention system\n\n\nPlugins\n-------\n* PLGN-1602 - Marked as root-only\n* PLGN-2612 - Marked as root-only\n* PLGN-2804 - Marked as root-only\n* PLGN-3202 - Marked as root-only\n\n\n--------------------------------------------------------------\n\nLynis 2.2.0 (2016-03-18)\n\nWe are proud to present this new release of Lynis. It is a major upgrade, and the\nresult of many months of work. This version includes new features and tests, and\nmany small enhancements. We encourage all to test and upgrade to this latest\nrelease.\n\n* Highlights\n------------\nThe biggest change in this release is the optimization of several functions. It\nallows for better detection, and dealing with the quirks, of every single\noperating system. Some functions were fortified to handle unexpected results\nbetter, like missing a particular binary, or not returning the hostname.\n\nThis release also enables tests to be shorter, by adding new functions. Some\nfunctions were renamed or slightly changed, to provide more value to the tooling.\nAnother big change in this release is a wide set of optimizations and quality\ntesting. Outdated pieces were removed, or rewritten, to support features seen in\nnewer distributions.\n\nIn the area of compliance, adjustments have been made to start supporting more\nin-depth testing for this. Ideal for companies who have a particular compliance\nneed, or want to test and enforce the system hardening levels of their systems.\n\nLast but not least, many small changes make this software easier to use. On\nour website we added new guides to provide help and support.\n\nWe like to thank our contributors, in particular Kamil Boratyński, Steve Bosek,\nand Eric Light. Their contributions helped us greatly shaping this release.\n\n\nBelow are the changes per category:\n\n* Automation tools\n------------------\nDetection for CFEngine has been improved. Also additional logging and reporting\nof automation tools.\n\n* Authentication\n----------------\nDepending on the operating system, Lynis now tries to determine if failed logins\nare properly logged. This includes checking for /etc/login.defs file [AUTH-9408].\nMerged previous password check for Solaris into test AUTH-9228. User ids on AIX\nwill be gathered and added to the report [AUTH-9234].\n\nNew plugin is introduced to analyze PAM settings. It including items like:\n\n- Two-factor authentication methods\n- Minimum password length, password strength and protection status against brute\n  force cracking\n- Password history\n\nReport option: auth_failed_logins_logged\n\n* Boot\n------\nAdded detection for Mac OSX boot loader. Initial support to test UEFI settings,\nincluding Secure Boot option. Options boot_uefi_booted and\nboot_uefi_booted_secure added to report file\n\n* Compliance\n------------\nThis release prepares for upcoming extensions to assist with compliance testing.\nThe profile has a new option, which can be used to define what standards should\nbe tested for, if any test is available. The related option is:\ncompliance_standards\n\nRight now these standards can be selected:\n- CIS benchmarks\n- HIPAA\n- ISO27001/ISO27002\n- PCI DSS\n\nNote that additional tests will be implemented in future releases and then tagged\nto these particular standards.\n\n* DNS and Name services\n-----------------------\nSupport added for Unbound DNS caching tool [NAME-4034], including a configuration\ncheck [NAME-4036].\n\nRecord if a name caching utility is being used like nscd or Unbound. Also logging\nto report as field name_cache_used\n\n* Firewalls\n-----------\nTest for IPFW firewall on FreeBSD has been improved: status of pflogd will no\nlonger be displayed, when pf is not available.\n\nNew test FIRE-4532 introduced for detection of the Mac OS X application firewall.\nAlso, the status of application firewalls is audited now.\n\nFIRE-4508 is another new test, which tests chains of iptables and their default\npolicy (ACCEPT or DROP). This release also supports the upcoming nftables\ntechnology with new test FIRE-4536. It is expected that it will replace iptables\nlater on, so this test will perform a status check. Additional FIRE-4548 will\nperform a version detection of the userland utility nft and determine if there\nare any rules configured.\n\nRenamed FIRE-4511 to FIRE-4502.\n\n* File Integrity Monitoring\n---------------------------\nTest added to include osqueryd as a supported tool.\n\n* Hardware\n----------\nDetection of firewire is enhanced (both ohci and core detected).\n\n* Logging\n---------\nExtended the test syslog-ng logging to remote systems. The log Lynis itself\nproduces is also enhanced, to be more detailed for several tests.\n\n* Malware\n---------\nESET and LMD (Linux Malware Detect) have been added. Discovered malware scanners\nare also logged to the report.\n\n* Mount points\n--------------\nFILE-6374 is expanded to test for multiple common mount points and define best\npractice mount flags.\n\n* Networking\n------------\nBest practices for IPv6 configuration on Linux are now collected. Also network\ninterface names from most operating systems.\n\n* Operating systems\n-------------------\nImproved support for Debian 8 systems, and displaying Gentoo for Gentoo-based\nsystems. Detection of VMware release has been added. Boot loader exception is not\nlonger displayed when only a subset of tests is performed. FreeBSD systems can\nnow use service command to gather information about enabled services.\n\nSeveral paths have been added to allow better detection on systems running\nFreeBSD and others.\n\n* Passwords\n-----------\nAUTH-9286 change has been extended to both capture minimum and password age.\n\n* Proxy support\n---------------\nA proxy can now be specified in the profile, to allow uploads via a HTTP or SOCKS\nproxy.\n\n* Service Managers\n------------------\nSystemV init is now detected.\n\n* Software and Packages\n-----------------------\nNow information will be logged when vulnerable software packages were found.\nSupport for DNF (Dandified YUM) for Fedora systems has been added. This is done\nin several tests: PKGS-7350 (installed packages), PKGS-7352 (security notices),\nPKGS-7354 (integrity tests).\n\n* SSH\n-----\nMultiple configuration tests of SSH are now merged into SSH-7408. This enables\neasier testing later on and reduces repetition.\n\n* Virtual machines and Containers\n---------------------------------\nDetection of virtual machines has been extended in several ways. Now VMware tools\n(vmtoolsd) are detected and machine state is improved with tools like Puppet\nFacter, dmidecode, and lscpu. Properly detect Docker on CoreOS systems, where it\nbefore gave error as it found directory /usr/libexec/docker. Check file\npermissions for Docker files, like the socket file [CONT-8108].\n\n* Individual tests\n------------------\n[AUTH-9204] Exclude NIS entries to avoid false positives\n[AUTH-9230] Removed test as it was merged into AUTH-9228\n[AUTH-9234] Support for AIX added\n[AUTH-9288] Test for expired passwords\n[AUTH-9328] Show correct message when no umask is found in /etc/profile. It also\n            includes improved logging, and support for other operating systems.\n[BOOT-5104] Rewrote test to detect SysV init and other service managers\n[BOOT-5106] New test to test boot loader on Mac OS X\n[BOOT-5180] Only gets executed if runlevel 2 is found\n[CONT-8108] New test to test for Docker file permissions\n[DBS-1816]  Removed suggestion\n[FILE-6310] Add more details to test when a symlinked path has been found\n[FILE-6410] Added /var/lib/locatedb as search path\n[FINT-4338] Added osquery test\n[FIRE-4508] Added chains test for iptables\n[FIRE-4511] Renamed to FIRE-4502\n[FIRE-4536] Support for nftables detection\n[FIRE-4538] Basic configuration check for for nftables\n[HOME-9310] Use POSIX compatible flags to avoid errors on BusyBox\n[HTTP-6622] Determine Apache version and log to report\n[HTTP-6624] Ignore wildcard and default entries as ServerName for Apache\n[LOGG-2154] Additional support for log destinations for syslog-ng\n[MALW-3278] New test to detect LMD (Linux Malware Detect)\n[NAME-4406] Changed logic for localhost check and more detailed logging\n[NETW-2600] IPv6 configuration check for Linux\n[NETW-3032] Added ARP monitoring software test\n[PKGS-7308] Split package name and version for RPM based package manager\n[PKGS-7350] Support for installed packages via Fedora DNF package manager (Dandified YUM)\n[PKGS-7352] Query security notices for DNF\n[PKGS-7354] Perform integrity tests for package database (DNF)\n[SHLL-6230] Test for umask values in shell configuration files (e.g. rc files)\n[STRG-1842] New test for checking authorized USB devices\n[TIME-3104] Show only suggestion on FreeBSD systems if ntpdate is configured\n[TIME-3170] New test to check NTP configuration files\n\n* Functions\n-----------\n[CreateTempFile]         Create a temporary file\n[DigitsOnly]             New function to extract only numbers from a text string\n[DisplayManual]          New function to show text on screen without any markup\n[ExitCustom]             New function to allow program to exit with a different exit code, depending on outcome\n[GetHostID]              If no MAC address is found, use SSH keys for creation of a host identifier\n[IsWordWritable]         Changed return codes for easier usage of the function\n[LogText]                Replaces the older logtext function\n[RandomString]           Creates a random string of characters\n[RemoveTempFiles]        Remove any created temporary files\n[Report]                 Replaces the older report function\n[ReportSuggestion]       Allows two additional parameters to store details\n                         (text and external reference to a solution)\n[ReportWarning]          Like ReportSuggestion() has additional parameters\n[ShowComplianceFinding]  Display compliance findings\n[ShowSymlinkPath]        Ensure readlink is available\n\n* General improvements\n----------------------\n- When using pentest mode, it will continue without any delays (=quick mode).\n- Plugins execution is improved, with improved logged and counting of active\n  plugins.\n- Data uploads: provide help when self-signed certificates are used.\n- Improved output for tests which before showed results as a warning, instead of\n  just as a suggestion.\n- Lynis now uses different exit codes, depending on errors or finding warnings.\n  This helps with automation and any custom scripting you want to apply.\n- Preparations to allow compressing the Lynis report file and enhance uploads.\n- Added --config option to show what settings file or profile is used.\n- Tool tips are displayed, to make Lynis even easier to use.\n- Show a warning if the release is older than four months.\n- PID file has additional checks, including cleanups.\n\n\n* Plugins\n---------\n[PAM]       New plugin available in all versions of Lynis\n[PLGN-2602] Replaced mktemp commands with CreateTempFile function\n[PLGN-2804] Limit report output of EXT file systems to 1 item per line\n\n--------------------------------------------------------------\n\nLynis 2.1.1 (2015-07-22)\n\nThis release adds a lot of improvements, with focus on performance, and\nadditional support for common Linux distributions and external utilities.\nWe recommend to use this latest version.\n\n* Operating system enhancements\n-------------------------------\nSupport for systems like CentOS, openSUSE, Slackware is improved.\n\n* Performance\n-------------\nPerformance tuning has been applied, to speed up execution of the audit on\nsystems with many files. This also includes code cleanups.\n\n* Automatic updates\n-------------------\nInitial work on an automatic updater has been implemented. This way Lynis\ncan be scheduled for automatic updating from a trusted source.\n\n* Internal functions\n--------------------\nNot all systems have readlink, or the -f option of readlink. The\nShowSymlinkPath function has been extended with a Python based check, which\nis often available.\n\n* Software support\n------------------\nApache module directory /usr/lib64/apache has been added, which is used on\nopenSUSE.\n\nSupport for Chef has been added.\n\nAdded tests for CSF's lfd utility for integrity monitoring on directories and\nfiles. Related tests are FINT-4334 and FINT-4336.\n\nAdded support for Chrony time daemon and timesync daemon. Additionally NTP\nsynchronization status is checked when it is enabled.\n\nImproved single user mode protection on the rescue.service file.\n\n* Other\n-------\nCheck for user permissions has been extended.\nPython binary is now detected, to help with symlink detection.\nSeveral new legal terms have been added, which are used for usage in banners.\nIn several files old tests have been removed, to further clean up the code.\n\n* Bug fixes\n---------\nNginx test showed error when access_log had multiple parameters.\nTests using locate won't be performed if not present.\nFix false positive match on Squid unsafe ports [SQD-3624].\nThe hardening index is now also inserted into the report if it is not displayed\non screen.\n\n* Functions\n---------\nAdded AddSystemGroup function\n\n* New tests\n---------\nSeveral new tests have been added:\n* [PKGS-7366] Scan for debsecan utility on Debian systems\n* [PKGS-7410] Determine amount of installed kernel packages\n* [TIME-3106] Check synchronization status of NTP on systemd based systems\n* [CONT-8102] Docker daemon status and gather basic details\n* [CONT-8104] Check docker info for any Docker warnings\n* [CONT-8106] Check total, running and unused Docker containers\n\n* Plugins\n---------\n* [PLGN-2602] Disabled by default, as it may be too slow for some machines\n* [PLGN-3002] Extended with /sbin/nologin\n\n* Documentation\n---------------\nA new document has been created to help with the process of upgrading Lynis.\nIt is available at https://cisofy.com/documentation/lynis/upgrading/\n\n--------------------------------------------------------------\n\n\nLynis 2.1.0 (2015-04-16)\n\n* General\n---------\nScreen output has been improved to provide additional information.\n\n* OS support\n------------\nCUPS detection on Mac OS has been improved. AIX systems will now use csum\nutility to create host ID. Group check have been altered on AIX, to include\nthe -n ALL. Core dump check on Linux is extended to check for actual values\nas well.\n\n* Software\n----------\nMcAfee detection has been extended by detecting a running cma binary.\nImproved detection of pf firewall on BSD and Mac OS. Security patch checking\nwith zypper extended.\n\n* Session timeout\n-----------------\nTests to determine shell time out setting have been extended to account for\nAIX, HP-UX and other platforms. It will now determine also if variable is\nexported as a readonly variable. Related compliance section PCI DSS 8.1.8\nhas been extended.\n\n* Documentation\n---------------\n- New document: Getting started with Lynis\n  https://cisofy.com/documentation/lynis/get-started/\n\n* Plugins (Enterprise)\n----------------------\n- Update to file integrity plugin\n  Changes to PLGN-2606 (capabilities check)\n\nNew configuration plugins:\n* PLGN-4802 (SSH settings)\n* PLGN-4804 (login.defs)\n\nDownload link: https://cisofy.com/download/lynis/\n\n--------------------------------------------------------------\n\n\nLynis 2.0.0 (2015-02-25)\n\n\nThe first release within the 2.x branch! It includes several new features, to\nsimplify or improve auditing on Unix based systems, including BSD, Linux,\nMac OS and more traditional systems like AIX, HPUX and Solaris.\n\nNew features and many improvements are the reason for the bump to a major\nrelease, also a beginning of a new era. Many tools to audit or harden systems\nhave being released, yet none have been maintained over a long period of time.\n\nLynis Support and Feedback\n--------------------------\nThis software is supported and under development by CISOfy. By providing a\ndual license, this software is kept up-to-date and enhanced. Both customers\nand the community, benefit from this licensing. This release is available\nthanks to your input and feedback.\n\nLynis Helpers\n-------------\nNew in this release is the support for helpers. Small utilities which enhance\nLynis by providing a single goal. The first helper available is to audit\nDocker build files.\n\nLynis Improved OS support\n-------------------------\nMany changes have been implemented to better support Linux, FreeBSD, NetBSD\nDragonBSD and OpenBSD in particular. Upcoming releases will include smaller\n\"improvement rounds\" for other systems as well.\n\nLynis New technologies\n----------------------\nMore utilities and technologies are supported now. Technologies and tools\nlike systemd, Docker, nftables.\n\nLynis Lynis Enterprise\n----------------------\nAs this code is shared, customers have an additional option to define to\nwhat server they want to upload the audit results. Also, commercial plugins\nhave been bundled.\n\nLynis New parameters\n--------------------\nSeveral new options have been added:\n* --dump-options (see all options)\n* --report-file (define a different location for the report file)\n\nLynis General\n-------------\nDocumentation on the website has been extended: https://cisofy.com/support/\nThe man page, Lynis binary and several tests have improved texts.\n\nThis release is exceptional in that it includes many changes. We have done\na lot of testing on different platforms. You could expect this software to be\nstable. Still, an assumption is no guarantee and especially no substitution\nfor testing in your own environment. If you encounter issues, please report\nthem via one of the links above in this changelog.\n\n\nEnjoy this new release!\n\n\n================================================================================\n\nLynis 1.6.4 (2014-11-04)\n\nNew:\n- Boot loader detection for AIX [BOOT-5102]\n- Detection of getcap and lsvg binary\n- Added filesystem_ext to report\n- Detect rootsh\n\nChanges:\n- Hide errors when RPM database is faulty and show suggestion instead [PKGS-7308]\n- Allow OpenBSD to gather information on listening network ports [NETW-3012]\n- Don't trigger warning for Shellshock when doing segfault test [SHLL-6290]\n- Do not run Apache test on OpenBSD and strip control chars [HTTP-6624]\n- Extended AIDE test with configuration validation test [FIND-4314]\n- Improved Shellshock test regarding non-Linux support [SHLL-6290]\n- Added support for gathering volume groups on AIX [FILE-6311]\n- Properly parse PAM lines and add them to report [AUTH-9264]\n- Support for boot loader detection on OpenBSD [BOOT-5159]\n- Added uptime detection for OpenBSD systems [BOOT-5202]\n- Support for volume groups on AIX [FILE-6312]\n- Redirect errors when searching for readlink binary\n\n---------------------------------------------------------------------------------\n\nLynis 1.6.3 (2014-10-14)\n\nNew:\n- Added tests for Shellshock bash vulnerability [SHLL-6290]\n- Added test to determine if Snoopy is used [ACCT-9636]\n- New test for qdaemon configuration file [PRNT-2416]\n- Test for GRUB boot loader password [BOOT-5122]\n- New test for qdaemon printer jobs [PRNT-2420]\n- Added ClamXav test for Mac OS X [MALW-3288]\n- Gentoo vulnerable packages test [PKGS-7393]\n- New test for qdaemon status [PRNT-2418]\n- Gentoo package listing [PKGS-7304]\n- Running Lynis without root permissions will start non-privileged scan\n- Systemd service and timer example file added\n- Added grub2-install to binaries\n\nChanges:\n- Adjustments so insecure SSL protocols are detected in nginx config [HTTP-6710]\n- Directories will be skipped when searching for nginx log files [HTTP-6720]\n- Only gather unique name servers from /etc/resolv.conf [NAME-2704]\n- Properly detect mod_evasive on Gentoo and others [HTTP-6640]\n- Improved swap partition detection in /etc/fstab [FILE-6336]\n- Improvements to kernel detection (e.g. Gentoo) [KRNL-5830]\n- Test for built-in security options in YUM [PKGS-7386]\n- Improved boot loader detection for GRUB2 [BOOT-5121]\n- Split GRUB test into two tests [BOOT-5122]\n- Added Mac OS uptime check [BOOT-5202]\n- Improved GetHostID function for systems having only ip binary\n- Improved testing for symlinked binary directories\n- Minor adjustments to log output\n- Renamed dev directory to extras\n\n---------------------------------------------------------------------------------\n\nLynis 1.6.2 (2014-09-22)\n\n New:\n - IsVirtualMachine function to check if system is running in VM\n\n   VM types: Bochs CPU emulation, IBM z/VM, KVM, Linux Containers,\n             libvirt LXC driver (Linux Containers), Microsoft Virtual PC, OpenVZ,\n             Oracle VM VirtualBox, QEMU, Systemd Namespace container,\n             User-Mode Linux (UML), VMware products, XEN\n\n - Detection for SaltStack configuration management tooling\n - ShowSymlinkPath function to check path behind a symlink\n - Check of configuration options of pacman [PKGS-7314]\n - Support for drill binary to check for Lynis update\n - FileIsEmpty function to check for empty files\n - Detect updates for Arch Linux [PKGS-7312]\n - Add detection for machine ID (systemd)\n - Added linux_config_file to report\n - Bash completion script for Lynis\n - Added detection of ss binary\n\n Changes:\n - Extended system reboot check, to enable it for most Linux  versions[KRNL-5830]\n - Improved inetd test to avoid false positive with xinetd process [INSE-8002]\n - Permissions check has been adjusted to allow packaging and pentest mode\n - Added detection for compressed Linux config file [KRNL-5728]\n - Added support for compressed Linux config file [KRNL-5730]\n - Store PID file in home directory of the user, if needed\n - Added usage of ss to gather listening ports [NETW-3012]\n - Additional permission added to CUPS check [PRNT-2307]\n - Extended telnet in inetd test [INSE-8016]\n - Fix for reading at.deny file [SCHD-7720]\n - Removed individual warnings [BOOT-5184]\n - Several improvements for Arch Linux\n\n---------------------------------------------------------------------------------\n\nLynis 1.6.1 (2014-09-09)\n\n New:\n - Added --pentest parameter to run a non-privileged scans (e.g. for pentesting)\n - Show skipped tests in report if they require root and scan is non-privileged\n\n Changes:\n - Improved vulnerable packages test on Debian based systems (apt-check) [PKGS-7392]\n - Don't show warnings for 'swap' in 4th column fstab file [FILE-6336]\n - Remove warning for old files in /tmp [FILE-6354]\n - CheckUpdates function will have better output when no connection is available\n - Changes to parameters and functions, to allow penetration tests with Lynis\n - Test for actual files in /etc/modprobe.d before grepping in it\n - Improved chown command when file permissions are incorrect\n - Changed output of update test, show when status is unknown\n - No scanning of symlinked directories (binaries test)\n - Extended SafePerms function to also check for UID\n - Several tests will have root-only bit set now\n - Improved netstat tests on Arch Linux\n\n---------------------------------------------------------------------------------\n\nLynis 1.6.0 (2014-08-27)\n\n New:\n - Added several new plugins to default profile\n - HostID detection for AIX\n\n Changes:\n - Improvements for log file\n - GetHostID function improved\n - Improved detection of security repository for Debian based systems [PKGS-7388]\n - Set default values for update check, to avoid error message on screen\n - Cleanup for mail section, adding IMAP and POP3 protocols\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.9 (2014-07-31)\n\n New:\n - New NetBSD test for vulnerable software packages [PKGS-7380]\n - Test if Debian based systems need a reboot [KRNL-5830]\n - Test for running Sendmail daemon [MAIL-8880]\n - Test for availability of mtree [FINT-4330]\n - Check for lp daemon (printing) [PRNT-2314]\n - Added Qmail status detection [MAIL-8860]\n - New NetBSD boot loader test [BOOT-5126]\n - Added test for automation tools like Cfengine and Puppet [TOOL-5002]\n - Added KRNL-5830 control to website\n - Added detection for Puppet\n - Added tooling category\n\n Changes:\n - Security repository test extended with /etc/apt/sources.list.d [PKGS-7388]\n - Added exception case for CUPS configuration (listen statement) [PRNT-2308]\n - Improved detection of TMOUT setting in shell profile file [SHLL-6220]\n - Perform promiscuous interfaces test for NetBSD as well [NETW-3014]\n - Perform swap partition parameters test on all systems [FILE-6336]\n - Also check password file on DragonFlyBSD and NetBSD [AUTH-9208]\n - Show message regarding toor user for all systems [AUTH-9204]\n - Check for available interfaces on NetBSD as well [NETW-3004]\n - Extended UFS file system test with FFS support [FILE-6329]\n - Improvements for step-tickers file test [TIME-3160]\n - Perform sockstat test for NetBSD [NETW-3012]\n - Gather IP addresses for NetBSD [NETW-3008]\n - Test MAC addresses on NetBSD [NETW-3006]\n - Added /usr/X11R7/bin directory to search for binaries\n - Improved full qualified domain name (FQDN) check for Linux\n - Don't show follow-up hints when there are no warnings or suggestions\n - Improved IsRunning function to better target processes\n - Several smaller adjustments in text and descriptions\n - Extended ReportException function with logging text\n - Improved GetHostID function for NetBSD and Solaris\n - Added printing_daemon and mail_daemon to report\n - Binaries extended with tools like kstat, puppet\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.8 (2014-07-24)\n\n New:\n - Testing for commercial anti-virus solutions like McAfee and Sophos [MALW-3280]\n - New control text for MALW-3280 - http://cisofy.com/controls/MALW-3280/\n\n Changes:\n - Extended GRUB test with encrypted password (SHA1) [BOOT-5121]\n - Check /etc/profile for multiple umask values [AUTH-9328]\n - Extended PHP disabled functions test [PHP-2320]\n - Add gpgcheck parameter to YUM test [PKGS-7387]\n - Squid configuration file permissions test adjusted and control added to website [SQD-3613]\n - Logging has been extended and exceptional event text adjusted\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.7 (2014-07-09)\n\n New:\n - Implementation of SafePerms function\n - Added notification when exceptions are found\n\n Changes:\n - Fix for error_log handling in nginx\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.6 (2014-06-12)\n\n New:\n - Test for PHP binary and PHP version\n - Don't perform register_global test for systems running PHP 5.4.0 and later [PHP-2368]\n - Debug function (can be activated via --debug or profile)\n\n Changes:\n - Extended IsRunning function\n - Removed suggestion from secure shell test [SHLL-6202]\n - Check for idle session handlers [SHLL-6220]\n - Also check for apache2 binary (file instead of directory)\n - New report values: session_timeout_enabled and session_timeout_method\n - New report value for plugins: plugins_enabled\n - Fixed test to determine active TCP sessions on Linux [NETW-3012]\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.5 (2014-06-08)\n\n New:\n - Check for nginx access logging [HTTP-6712]\n - Check for missing error logs in nginx [HTTP-6714]\n - Check for debug mode in nginx [HTTP-6716]\n\n Changes:\n - Extended SSL test for nginx when using listen statements\n - Allow debugging via profile (config:debug:yes)\n - Check if discovered httpd file is actually a file\n - Improved temporary file creation related to security notice\n - Adjustments to screen output\n\n Security Note:\n This releases solves two issues regarding the usage of temporary\n files (predictability of the file names). You are advised to upgrade\n to this version as soon as possible. For more information see the\n our blog post: http://linux-audit.com/lynis-security-notice-154-and-older/\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.4 (2014-06-04)\n\n New:\n - Check additional configuration files for nginx [HTTP-6706]\n - Analysis of nginx settings [HTTP-6708]\n - New test for SSL configuration of nginx [HTTP-6710]\n\n Changes:\n - Altered SMBD version check for Mac OS\n - Small adjustments to report for readability\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.3 (2014-05-19)\n\n New:\n - Support for zypper package manager\n - Gather installed packages with Zypper on SuSE systems [PKGS-728]\n - Check for vulnerable packages with Zypper package manager [PKGS-7330]\n\n Changes:\n - Check for aide.conf also in /etc [FINT-4315]\n - Adjusted screen output for unreliable NTP peers [TIME-3120]\n - Adjusted check kernel test for non-Linux systems [KRNL-5730]\n - Improved screen output on AIX systems with echo command\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.2 (2014-05-05)\n\n New:\n - Support for runlevel in binaries test\n\n Changes:\n - Added suggestion for kernel availability check [KRNL-5788]\n - Added suggestion for services at startup and proper binary call [BOOT-5180]\n - Added suggestion to configure accounting on FreeBSD [ACCT-2754]\n - Added suggestion to configure Linux process accounting [ACCT-9622]\n - Several new controls listed on website\n - Adjusted hardening index if total score was zero\n - Added suggestion for auditd.conf file [ACCT-9632]\n - Removed suggestion for audit log file [ACCT-9634]\n - Removed warning from NTP falsetickers test, added data to report [TIME-3132]\n - Removed warning from NTP selected time source test [TIME-3124]\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.1 (2014-04-22)\n\n Changes:\n - Extended reporting with running databases and frameworks\n - Adjusted Oracle status in test [DBS-1840]\n - Extended grsecurity test [RBAC-6272]\n - Redirect rpcinfo errors to /dev/null\n - Adjusted color scheme\n\n---------------------------------------------------------------------------------\n\nLynis 1.5.0 (2014-04-10)\n\n New:\n - Support for Amazon Linux\n - NTP check for step-tickers file (Red Hat and clones) [TIME-3160]\n\n Changes:\n - Minor textual changes in description of several controls\n - Removed several warnings (usage of suggestions instead)\n - Website has now more information for several controls\n - Extended detection for Oracle Linux\n - Updated the FAQ and README files\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.9 (2014-04-03)\n\n New:\n - Added links in report to related control documentation on website\n - Detect Linux I/O kernel scheduler [KRNL-5730]\n\n Changes:\n - Check for non-unique accounts on several platforms [AUTH-9208]\n - Set initial discover value for PAM modules to zero [AUTH-9268]\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.8 (2014-03-27)\n\n Changes:\n - Adjusted resolv.conf domain setting in report [NAME-4016]\n - Extend account test with /var/log/pacct [ACCT-9620]\n - Added suggestion to DNS domain name test [NAME-4028]\n - Changed text strings of ZFS test [FILE-6330]\n - Extend LILO password test [BOOT-5139]\n - Set default value for pf firewall\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.7 (2014-03-21)\n\n New:\n - New configuration item to set group name\n - Search for AIDE configuration file (aide.conf) [FINT-4315]\n - Check for usage of SHA256/SHA512 in AIDE configuration [FINT-4316]\n - Added grep to list of binaries\n\n Changes:\n - Added suggestion when using NIS or NIS+ [NAME-4302]\n - Clean-up of unneeded plugin section\n - Small typo fix\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.6 (2014-03-14)\n\n New:\n - Check for GPG signing in yum.conf [PKGS-7387]\n - Check CUPS configuration file permissions [PRNT-2307]\n\n Changes:\n - Screen cleanup\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.5 (2014-03-08)\n\n New:\n - Support for Chakra Linux\n - Support for pacman binary (package manager)\n - Query installed packages on systems with pacman [PKGS-7310]\n\n Changes:\n - Avoid logging to screen when falsetickets are found [TIME-3132]\n - Skipping FIFO file on Solaris systems when checking for cron jobs [TIME-3104]\n - Extended uptime test for Solaris systems [BOOT-5202]\n - Added /usr/lib/security to PAM locations to scan\n - Report cronjobs to report [SCHD-7704]\n - HostID support for Solaris\n - Improved color scheme\n - Extended logging\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.4 (2014-03-03)\n\n New:\n - Detect tune2fs binary\n - Added ExitFatal() function\n - Added egrep binary to binaries\n - Initial plugin support (phase 1)\n - Added InsertPluginSection() function\n\n Changes:\n - Adjusted disabled functions tests to properly find functions [PHP-2320]\n - Extended time test with egrep binary replace for Solaris [TIME-3104]\n - Adjusted color for SNMP test when warning is found [SNMP-3306]\n - Adjusted text for PHP risky functions [PHP-2320]\n - Refer to discovered binaries for ifconfig, lsmod, tune2fs\n - Test plugin directory when provided by --plugin-dir\n - Scan report extended with plugin information\n - Extended help for Enterprise options\n - Improved IsRunning() function\n - Extended color scheme\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.3 (2014-02-23)\n\n New:\n - Support for ClearOS\n - Data upload for Lynis Enterprise users (--upload)\n - Added debug variable for troubleshooting purposes\n - Scan profile option license_key\n\n Changes:\n - Skip password check for Red Hat or clones [AUTH-9282]\n - Extended single user login protection [AUTH-9308]\n - Adjusted repolist check for yum based systems [PKGS-7383]\n - Inserted sleep time when update is found\n - Extended report output\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.2 (2014-02-19)\n\n Changes:\n - Ignore interfaces aliases for HostID\n - Extended umask tests with pam_umask entries [AUTH-9328]\n - Check for suppressed version on Squid [SQD-3680]\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.1 (2014-02-15)\n\n New:\n --plugin-dir parameter\n\n Changes:\n - Added 64 bits locations for Apache modules\n - Add start of new category to logfile\n - Extended sysstat test with /etc/cron.d/sysstat [ACCT-9626]\n - Extended cron job tests with entries start with asterisk (*) [SCHD-7704]\n - Additional check for multiple umask entries (like RHEL 6.x) [AUTH-9328]\n - Adjusted PHP test for register_globals (explicit test) [PHP-2368]\n - Small adjustments for upcoming plugin support\n - Extended man page\n\n---------------------------------------------------------------------------------\n\nLynis 1.4.0 (2014-01-29)\n\n Changes:\n - Removed some warnings, to prevent double messages\n - Extended accounting check for Linux [ACCT-9622]\n - Added consistency check to time test [TIME-3124]\n - Added support for anacron jobs [SCHD-7704]\n - Rewrite of YUM repository test [PKGS-7383]\n - Use binary variables for hostid creation\n - AIX version detection changed\n - Added rpcinfo to binaries check\n - Ignore LANG global setting\n - Improved logging\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.9 (2014-01-09)\n\n Changes:\n - Additional support for Mac OS\n - Support for shasum binary\n - Performance adjustment for lsof tests\n - Extended interface check for hostid creation\n - Improved NSCD detection [NAME-4032]\n - Bug fix for passwdqc [AUTH-9262]\n - Extended vulnerable packages test [PKGS-7392]\n - Hide possible sysctl errors [KRNL-5820]\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.8 (2013-12-25)\n\n New:\n - New parameter --view-categories to display available test categories\n - Added /etc/hosts check (duplicates) [NAME-4402]\n - Added /etc/hosts check (hostname) [NAME-4404]\n - Added /etc/hosts check (localhost mapping) [NAME-4406]\n - Portmaster test for possible port upgrades [PKGS-7378]\n - Check for SPARC improve boot loader (SILO) [BOOT-5142]\n - NFS client access test [STRG-1930]\n - Check system uptime [BOOT-5202]\n - YUM repolist check [PKGS-7383]\n - Contributors file added\n\n Changes:\n - Improved locate database check and reporting [FILE-6410]\n - Improved PAE/No eXecute test for Linux kernel [KRNL-5677]\n - Disabled NIS domain name from test [NAME-4028]\n - Extended NIS domain test to check BSD sysctl value [NAME-4306]\n - Extended PAM tools check with PAM paths [AUTH-9262]\n - Adjusted Apache check to avoid skipping it [HTTP-6622]\n - Extended USB state testing [STRG-1840]\n - Extended Firewire state testing [STRG-1846]\n - Extended core dump test [KRNL-5820]\n - Added /lib/i386-linux-gnu/security to PAM directories\n - Added /usr/X11R6/bin directory to binary paths\n - Improved readability of screen output\n - Improved logging for several tests\n - Improved Debian version detection\n - Added warning to BIND test [NAME-4206]\n - Extended binaries with showmount and yum\n - Updated man page\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.7 (2013-12-10)\n\n New:\n - Function FileExists() and SearchItem()\n\n Changes:\n - Adjusted yum-security check [PKGS-7386]\n - Improved check for iptables binary check\n - Extended report with the tests executed and skipped\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.6 (2013-12-03)\n\n New:\n - Support for the dntpd time daemon\n - New Apache test for modules [HTTP-6632]\n - Apache test for mod_evasive [HTTP-6640]\n - Apache test for mod_qos [HTTP-6641]\n - Apache test for mod_spamhaus [HTTP-6642]\n - Apache test for ModSecurity [HTTP-6643]\n - Check for installed package audit tool [PKGS-7398]\n - Added initial support for new pkgng and related tools [PKGS-7381]\n - Check for ssh-keyscan binary\n - ZFS support for FreeBSD [FILE-6330]\n - Test for passwordless accounts [AUTH-9283]\n - Initial OS support for DragonFly BSD\n - Initial OS support for TrueOS (FreeBSD based)\n - Initial OS support for elementary OS (Luna)\n - GetHostID for DragonFly, FreeBSD, NetBSD and OpenBSD\n - Check for DHCP client [NETW-3030]\n - Initial support for OSSEC (system integrity) [FINT-4328]\n - New parameter --log-file to adjust log file location\n - New function IsRunning() to check status of processes\n - New function RealFilename() to determine file name\n - New function CheckItem() for parsing files\n - New function ReportManual() and ReportException() to simplify code\n - New function DirectoryExists() to check existence of a directory\n - Support for dntpd [TIME-3104]\n\n Changes:\n - Extended pf checks for FreeBSD/OpenBSD and others [FIRE-4518]\n - Extended test to gather listening network ports for Linux [NETW-3012]\n - Adjusted lsof statement to ignore warnings (e.g. fuse) [LOGG-2180] [LOGG-2190]\n - Added suggestion for discovered shells on FreeBSD [AUTH-9218]\n - Extended core dump test with additional details [KRNL-5820]\n - Properly display suggestion if portaudit is not installed [PKGS-7382]\n - Ignore message if no packages are installed (pkg_info) [PKGS-7320]\n - Also try using apt-check on Debian systems [PKGS-7392]\n - Adjusted logging for RPM binary on systems not using it [PKGS-7308]\n - Extended search in cron directories for rdate/ntpdate [TIME-3104]\n - Adjusted PHP check to find ini files [PHP-2211]\n - Skip Apache test for NetBSD [HTTP-6622]\n - Skip test http version check for NetBSD [HTTP-6624]\n - Additional check to suppress sort error [HTTP-6626]\n - Improved the way binaries are checked (less disk reads)\n - Adjusted ReportWarning() function to skip impact rating\n - Improved report on screen by leaving out date/time and type\n - Redirect errors while checking for OpenSSL version\n - Extended reporting with firewall status and software\n - Adjusted naming of some operating systems to make them more consistent\n - Extended update check by using host binary if dig is not installed\n - Count number of installed binaries/packages and report them\n - Report about log rotation tool and status\n - Updated man page\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.5 (2013-11-19)\n\n New:\n - OS detection for Mageia Linux, PCLinuxOS, Sabayon Linux and Scientific Linux\n - Added some initial systemd support (e.g. boot services)\n - Test to display if any known MAC framework is implemented [MACF-6290]\n\n Changes:\n - Improved support for Slackware Linux (OS and version detection)\n - Added systemd support (boot and running services) for Linux systems [BOOT-5177]\n - Added systemd support (default runlevel) for Linux systems [KRNL-5622]\n - Extended USB storage check in modprobe.d directory [STRG-1840]\n - Improved output, reporting and check for kernel update [KRNL-5788]\n - Optimized code and output of test to check writable scripts [BOOT-5184]\n - Fixed detection for writable scripts [BOOT-5184]\n - Improved detection IPv6 addresses for Slackware and others [NETW-3008]\n - Minor addition to SSH PermitRootLogin check [SSH-7412]\n - Extended cronjob tests, reporting and logging [SCHD-7704]\n - Extended umask check in /etc/profile [AUTH-9328]\n - Added suggestion about BIND version [NAME-4210]\n - Merged test NTP daemon test TIME-3108 into TIME-3104\n - Improved support for Arch Linux (output, detection)\n - Extended common list of directories with SSL certificates in profile\n - New function GetHostID() to determine an unique identifier of the machine\n - Added a tests_custom file template\n - Perform file permissions test on tests_custom file\n - Improved OS detection and extended logging on several tests\n - Several layout improvements\n - Extended update check functions and output\n - Cleaned up reporting and extended it with exceptions\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.4 (2013-11-08)\n\n New:\n - OS detection support for Arch Linux\n - Support for systemd journal\n\n Changes:\n - Test for files in /etc/modprobe.d directory [STRG-1840]\n - Extended log daemon detection with systemd journal [LOGG-2130]\n - Adjusted hardening value for compiler GCC [HRDN-7222]\n - Extended IsWorldWritable and IsWorldExecutable functions to support symlinks\n - Adjusted PHP test for disabled functions [PHP-2320]\n - Extended testing for PHP files in other directories [PHP-2211]\n - Improved screen output for several tests and extended logging\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.3 (2013-10-24)\n\n New:\n - Added NTP configuration type to report [TIME-3104]\n\n Changes:\n - Do not warn on empty shells for FreeBSD systems [AUTH-9218]\n - Extended checks for presence NTP client or daemon [TIME-3104]\n - Extended logging\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.2 (2013-10-09)\n\n New:\n - Test for PowerDNS authoritative servers (master/slave status) [NAME-4238]\n\n Changes:\n - CUPS test extended with hardening rules [PRNT-2308]\n - Added hardening points to sticky bit on /tmp [FILE-6362]\n - Extended Ubuntu security packages check [PKGS-7392]\n - Improved update check, show when no check is performed\n - Added additional check for binaries, so checks on CentOS work correctly\n - Added word 'restricted' to banner strings\n - Adjusted wording for Debian packages purge [PKGS-7346]\n - Corrected listing of purgable packages [PKGS-7346]\n - Adjusted yum-plugin-security check due to package changes [PKGS-7386]\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.1 (2013-10-02)\n\n Changes:\n - Updated generic references in files\n - Fixed detection of several binaries (AFICK/awk)\n - Performance tweaks when checking for binaries\n - Fixed core dump check and dumpable sysctl [KRNL-5820]\n - Force test to always to check for binaries [FILE-7502]\n - Changed detection to egrep [DBS-1840]\n - Adjusted variable checking for Solaris [HOME-9310]\n - Adjusted search in modprobe directory [STRG-1840] [STRG-1846]\n\n---------------------------------------------------------------------------------\n\nLynis 1.3.0 (2011-12-25)\n\n New:\n - Profile option: ignore_home_dir\n - TCP wrappers category added\n - Tooling category added\n - Initial extensions to support plugins in the future\n - Test for unpurged Debian packages [PKGS-7346]\n - Test for compiler permissions [HRDN-7222]\n\n Changes:\n - Converted all dates to ISO format and updated copyright lines\n - Correct suggestion for file integrity tool [FINT-4350]\n - Added hint when RPM list is empty on DPKG based systems [PKGS-7308]\n - Changed logging for /etc/security/limits.conf file [KRNL-5820]\n - Fixed incorrect warning for single user mode [AUTH-9308]\n - Improved output for stratum 16 time servers [TIME-3116]\n - Added suggestion and screen output for kernel hardening [KRNL-6000]\n - Screen layout optimizations and log file improvements\n - Improved list/layout of scan options\n - Improved binary check for compilers\n - Added configuration option in scan profile (show_tool_tips, default true)\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.9 (2009-12-15)\n\n New:\n - Support for Squid3\n - Added Squid unsafe ports check [SQD-3624]\n - Added Squid configuration file permission check [SQD-3613]\n - Added Squid test: reply_body_max_size option [SQD-3630]\n - Added /etc/init.d/rc and /etc/init.d/rcS to umask test [AUTH-9328]\n - Check PHP option allow_url_include [PHP-2378]\n\n Changes:\n - Extended possible Squid configuration file locations\n - Added additional sysctl keys to default profile\n - Fixed typo in squid.conf checks\n - Improved descriptions, logging and reporting for several tests\n - Corrected /etc/security/limits.conf path in test [KRNL-5820]\n - Updated man page, limited lines to 80 chars\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.8 (2009-12-08)\n\n New:\n - Squid support added\n - Squid daemon detection [SQD-3602]\n - Squid configuration file search [SQD-3604]\n - Squid version detection [SQD-3606]\n - Check /etc/motd banner [BANN-7122]\n - Check /etc/issue.net file [BANN-7128]\n - Check contents in /etc/issue.net [BANN-7130]\n - Solaris single user mode login check (/etc/default/sulogin) [AUTH-9304]\n - HP-UX boot authentication check [AUTH-9306]\n - Linux single user mode authentication check [AUTH-9308]\n - Solaris account locking policy check [AUTH-9340]\n\n Changes:\n - Added prerequisite to SSH test, so the test is skipped properly [SSH-7440]\n - Check for /etc/issue symlink [BANN-7124]\n - Added file check for possible harmful shells found [AUTH-9218]\n - Add user home directories to report [HOME-9302]\n - Extended Linux run level test with support for Debian/Ubuntu [KRNL-5622]\n - Added /lib64/security to PAM test [AUTH-9262]\n - Extended security repository check [PKGS-7388]\n - Iptables check should not check for a module in a Linux config [FIRE-4511]\n - Ignore APC ups daemon when scanning for CUPS [PRNT-2304]\n - Improved kernel logger daemon check [LOGG-2138]\n - Added auditctl to binary check [ACCT-9630]\n - Log used auditd ruleset [ACCT-9630]\n - Corrected logging of Solaris c2audit module [ACCT-9656]\n - Fixed warning function for Solaris passwordless accounts [AUTH-9254]\n - Commented kern.randompid in default profile\n - For sysctl the parameter -n will be used on Linux systems\n - Changed syslog daemon detection and state\n - Extended report file\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.7 (2009-11-01)\n\n New:\n - Added Kernel Hardening section\n - Sysctl audit support in scan profile and related test [KRNL-6000]\n - SSH option StrictModes test [SSH-7416]\n - Password aging limit check [AUTH-9286]\n - Ubuntu packages check (apt-show-versions) [PKGS-7394]\n - Check for metalog daemon [LOGG-2210]\n - USB storage driver state check [STRG-1840]\n - Firewire storage driver state check [STRG-1846]\n - PostgreSQL process check [DBS-1826]\n - Oracle process check [DBS-1840]\n - Default umask check [AUTH-9328]\n - Check for rsyslog daemon [LOGG-2230]\n - RFC 3195 compliant daemon check [LOGG-2240]\n - Qmail SMTP daemon check [MAIL-8940]\n - Test for separation of /tmp and /home from root file system [FILE-6310]\n - SSH AllowUsers and AllowGroups usage check [SSH-7440]\n - AIX support, thanks to Michael Smerdka\n\n Changes:\n - Fixed crontabs path [SCHD-7704]\n - Extended locate database paths for Linux and FreeBSD [FILE-6410]\n - pflog detection fix [FIRE-4518]\n - Skip /proc/meminfo for non Linux systems [PROC-3602]\n - Extended text with rsyslogd [LOGG-2130]\n - Ignore comment and empty lines for group tests [AUTH-9222/9226]\n - Show firewall as active when iptables is available in config file [FIRE-4511]\n - Variable fix for SNMP daemon configuration file [SNMP-3304]\n - Freshclam check fix [MALW-3286]\n - Fixed waiting search for NIS domain [NAME-4306]\n - Check for a maximum of 1 search statement in /etc/resolv.conf [NAME-4018]\n - Apache test improved [HTTP-6622]\n - Skip klogd test if rsyslogd is available [LOGG-2138]\n - Added additional CUPS location to search paths\n - Only execute PAM test for systems with PAM [AUTH-9268]\n - Fixed logging of sudoers file location [AUTH-9250]\n - Improved FreeBSD support for NTP client check [TIME-3104]\n - Redirect warning \"Unknown host\" when DNS domain name is empty [NAME-4028]\n - Redirect warning when host name is empty\n - Fixed warning color [AUTH-9226]\n - Fixed FreeBSD COPYRIGHT file test [BANN-7113]\n - Changed text for sudoers text [AUTH-9250]\n - Improved text for DNS search domain [NAME-4016]\n - Skip nginx configuration test if nginx is not available [HTTP-6704]\n - Removed portsclean suggestion [PKGS-7348]\n - Fixed non unique IDs\n - Fixed cosmetic issue when using Debian with default dash shell\n - Improved hostname detection for HP-UX\n - Added additional php.ini file locations\n - Moved Linux default shell check to OS detection functions\n - Fixed CUPS daemon test [PRNT-2304]\n - Also check for uppercase chars in issue file [BANN-7126]\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.6 (2009-04-05)\n\n New:\n - Sudoers file permissions check [AUTH-9252]\n - Core dumps configuration check for Linux [KRNL-5820]\n - PHP disabled functions check [PHP-2320]\n - PHP enable_dl function check [PHP-2374]\n - PHP allow_url_fopen function check [PHP-2376]\n - OpenBSD smtpd status check [MAIL-8920]\n - /etc/issue check [BANN-7124]\n - /etc/issue legal keywords check [BANN-7126]\n - Show suggestions in report\n\n Changes:\n - Extended support for Red Hat, CentOS and Fedora\n - Extended ACL test to test for default mount options as well [FILE-6368]\n - Exim status test fixed [MAIL-8812]\n - Corrected yum security check [PKGS-7386]\n - Replaced LDAP test AUTH-9238 with [AUTH-9402]\n - Removed backquotes when locate database is not available [FILE-6410]\n - Added /etc/openldap to search path for OpenLDAP\n - Fixed typo in crontab path [SCHD-7704]\n - Don't show message \"No volume groups found\" if LVM isn't used [FILE-6310]\n - Corrected Syslog-NG status [LOGG-2132]\n - Moved TODO to dev directory\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.5 (2009-03-27)\n\n New:\n - slapd.conf check [LDAP-2224]\n - atd status test [SCHD-7718]\n - Check LDAP module in PAM [AUTH-9278]\n - Check Dovecot status check [MAIL-8838]\n - Check log directories from newsyslog.conf [LOGG-2162]\n - Check log directories from static list [LOGG-2170]\n - Check log directories from logrotate configuration [LOGG-2150]\n - syslog check for remote logging [LOGG-2154]\n - Open log files check [LOGG-2180]\n - Deleted file check [LOGG-2190]\n - Solaris active kernel modules check [KRNL-5770]\n - Solaris audit daemon status check [ACCT-9650]\n - Solaris audit daemon service status [ACCT-9652]\n - Solaris audit daemon BSM check [ACCT-9654]\n - Solaris audit logging location check [ACCT-9662]\n - Solaris audit statistics check [ACCT-9672]\n - Check for installed compiler [HRDN-7202]\n - BIND process check [NAME-4202]\n - BIND configuration file check [NAME-4204]\n - BIND configuration consistency check [NAME-4206]\n - BIND version check via DNS [NAME-4210]\n - Default domain check (/etc/resolv.conf) [NAME-4016]\n - Search domains in /etc/resolv.conf check [NAME-4018]\n - Parse /etc/resolv.conf options [NAME-4020]\n - Solaris /etc/nodename check [NAME-4026]\n - DNS domain checks [NAME-4028]\n - NSCD status check [NAME-4032]\n - PowerDNS presence check [NAME-4230]\n - PowerDNS configuration file check [NAME-4232]\n - PowerDNS backend check [NAME-4236]\n - ypbind status check [NAME-4302]\n - Log specific defined SSH daemon options [SSH-7408]\n - SSH protocol version check [SSH-7414]\n - NIS domain checks [NAME-4304]\n - Check pending at jobs [SCHD-7724]\n - LVM volume group scan [FILE-6310]\n - LVM volumes check [FILE-6312]\n - Locate database check [FILE-6410]\n - nginx configuration file check [HTTP-6704]\n - Exim status check [MAIL-8802]\n - Postfix status check [MAIL-8814]\n\n Changes:\n - atd needs to run before testing at files [SCHD-7720]\n - Removed Solaris OS requirement from logrotate test [LOGG-2148]\n - Sanitized output from logrotate test [LOGG-2148]\n - Skip comment fields in loghost check [LOGG-2152]\n - Changed auditd tests to Linux only\n - Binary scan optimized and partially combined with other check\n - Only perform iptables tests if kernel module is active\n - Don't show message when /etc/shells can't be found [SHLL-6211]\n - Check /var/spool/cron/crontabs first, if it exists [SCHD-7704]\n - Renumbered FreeBSD test SHLL-7225 [SHLL-6202]\n - Renumbered malware test MALW-3292 [HRDN-7230]\n - Improved grep on process status [PRNT-2304]\n - Ignore comment lines for nginx log file check [HTTP-6720]\n - Added file check for nginx log files [HTTP-6720]\n - Display IP addresses only of NTP tests [TIME-3124]\n - Fixed Postfix configuration directory path [MAIL-8816]\n - Redirected output of yum package duplicate check [PKGS-7384]\n - Ignore comment lines for lilo test [BOOT-5139]\n - Fixed incorrect iptables status and correct logging [FIRE-4511]\n - Check SNMP configuration only if SNMP daemon runs [SNMP-3304]\n - Don't scan PAM directories which are symlinks [AUTH-9268]\n - Changed hardening category to hardening_tools\n - Adjusted hardening points of several tests\n - Log and display improvements for several tests\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.4 (2009-03-17)\n\n New:\n - NTP daemon process test [TIME-3108]\n - NTP association ID's check from peer list [TIME-3112]\n - NTP time source candidates test [TIME-3128]\n - NTP falseticker check [TIME-3132]\n - NTP protocol version check [TIME-3136]\n - Stratum 16 ntp peers check [TIME-3116]\n - Unreliable ntp peers check [TIME-3120]\n - Preferred NTP time source test [TIME-3124]\n - auditd presence check [ACCT-9628]\n - auditd rules check [ACCT-9630]\n - auditd configuration file check [ACCT-9632]\n - auditd log file location check [ACCT-9634]\n - cupsd status check [PRNT-2304]\n - cupsd configuration file check [PRNT-2306]\n - cupsd address configuration test [PRNT-2308]\n - pam.conf configuration check [AUTH-9264]\n - pam.d configuration file scan [AUTH-9266]\n - PAM modules check [AUTH-9268]\n - rpcinfo query [STRG-1902]\n - NFS version number check [STRG-1904]\n - NFS protocol and port number check [STRG-1906]\n - NFS status check [STRG-1920]\n - NFS exports check [STRG-1926]\n - NFS empty /etc/exports [STRG-1928]\n - SSH PermitRootLogin option check [SSH-7412]\n - at.allow and at.deny check [SCHD-7720]\n - File integrity tool check [FINT-4350]\n - nginx process check [HTTP-6702]\n - nginx log file test [HTTP-6720]\n - ClamAV clamscan presence test [MALW-3282]\n - ClamAV daemon check [MALW-3284]\n - ClamAV freshclam check [MALW-3286]\n - Check for presence malware scanner [MALW-3292]\n - clamscan, ntpq binary check\n - NTP daemon role and profile option\n - Parameter --tests-category, to scan one or more categories\n - Category added (Storage: NFS)\n - Added hardening points to tests\n - Display hardening index to report\n\n Changes:\n - Extended logrotate test [LOGG-2148]\n - Added check for inetd.conf before performing test [INSE-8016]\n - Added /var/spool/crontabs to search path [TIME-3104]\n - Added log line to sysstat test [ACCT-9626]\n - Improved screen output on Solaris\n - Checking for both rdate and ntpdate in cron files [TIME-3104]\n - Changed yum-security package check [PKGS-7386]\n - Change output if dig isn't available [NETW-2705]\n - Added IPv6 support and output adjustment [NETW-2704]\n - Cosmetic change for host based firewall check [FIRE-4590]\n - Corrected output in log file [PKGS-7388]\n - Corrected passwd options for Red Hat [AUTH-9282]\n - Changed text if everything is ok (no warnings)\n - Log improvements\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.3 (2009-03-02)\n\n New:\n - Added syslog-NG daemon check [LOGG-2132]\n - Added klogd status test [LOGG-2138]\n - Added check to determine minilogd presence [LOGG-2142]\n - Added logrotate configuration test [LOGG-2146]\n - Added check for loghost entry on Solaris machines [LOGG-2152]\n - Added ipf test for Solaris [FIRE-4526]\n - Added uname -n test (Solaris) [NAME-4024]\n - Added ssh daemon configuration file check [SSH-7404]\n - Added BSD newsyslog.conf file check [LOGG-2160]\n - Added inetd status check [INSE-8002]\n - Added inetd.conf configuration check [INSE-8004]\n - Added check for inetd.conf when inetd is not active [INSE-8006]\n - Added telnet check via inetd [INSE-8016]\n - Added ACL check on root file system [FILE-6368]\n - Added check for firewall/packet filter on system [FIRE-4590]\n - Added lograte file check [LOGG-2148]\n - Added snmp daemon status test [SNMP-3302]\n - Added snmp configuration file test [SNMP-3304]\n - Added default snmp community strings test [SNMP-3306]\n - Added categories: Insecure services and SNMP\n - Added binary searches for awk, ipf\n\n Changes:\n - Changed profile name in default profile\n - Added path /usr/ucb to binary paths\n - Changed color to white if slapd is not running [LDAP-2219]\n - Changed test PKG-7345 into PKGS-7345\n - Changed logging for several tests [PKGS-7302] [NETW-3004]\n - Extended FAQ\n - Changed default profile header\n\n Fixes:\n - Hostname detection under Solaris\n - Disabled tests PROC-3612 PROC3614 for Solaris machines\n - Disabled NTP check in cron.d directory on Solaris [TIME-3104]\n - Added result at line when querying system users [AUTH-9234]\n - Counters (N+1) fixed for some shells, like Solaris\n - Removed unneeded line for Solaris test [PROC-3604]\n - Disabled grsecurity test for Solaris [RBAC-6272]\n - Correct display of files with spaces [FILE-6354]\n - Changed several tests so they work correctly with Solaris\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.2 (2009-02-15)\n\n New:\n - Support for MySQL client\n - New test: Test for empty MySQL root password [DBS-1816]\n - New test: SSH daemon status test [SSH-7402]\n - New test: sysstat account information [ACCT-9626]\n - New test: connections in WAIT state [NETW-3028]\n - Lynis displays a warning now, if current version is really outdated\n - New parameter option (log_tests_incorrect_os) to minimize logging\n\n Changes:\n - Several adjustments to default profile\n - Fixed option 'skip_test_always' to let it function properly\n - Fixed passwd check for SuSE systems [AUTH-9282]\n - Added error redirect for dpkg test [PKG-7345]\n - Improved NTP test and messages, excluded check when using xen [TIME-3104]\n - Extended DNS nameserver check with local resolver [NETW-2704]\n - Skip double nameserver check when a local resolver is found [NETW-2705]\n - Renamed tests_nameserver to tests_nameservices\n - Improved log output [AUTH-9218]\n\n Notes:\n - Custom profiles should be compared to the default profile, due small changes\n   in the structure.\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.1 (2008-09-05)\n\n New:\n - Added support for Samba\n - Added support for SELinux framework\n - New test: SELinux presence test [MACF-6232]\n - New test: SELinux status checks [MACF-6234]\n - New test: password PAM availability check [AUTH-9262]\n - New test: expire date check for accounts [AUTH-9282]\n - Added new option --tests, to run a small set of tests only\n\n Changes:\n - Report and logging messages improved\n - Output reduced when using --tests\n - Added suggestion to PHP expose_php option [PHP-2372]\n - Improved log message for PHP register_globals option [PHP-2368]\n - Added virtual host count to log file [HTTP-6626]\n - Improved Red Hat and clones detection and display\n - Fix: Improved promiscuous detection for Linux [NETW-3015]\n - Fix: AUTH-9204 test triggered on group ids as well\n - Fix: Only display unique MAC addresses [NETW-3006]\n - Extended Postfix test [MAIL-8818]\n - Don't show /proc/meminfo if not present [PROC-3602]\n - Don't show YABOOT information if not present [BOOT-5155]\n - Improved portaudit test (FreeBSD) [PKGS-7382]\n - Improved portsclean test (FreeBSD) [PKGS-7348]\n - Added --quiet and --tests options to help and man page\n\n---------------------------------------------------------------------------------\n\nLynis 1.2.0 (2008-08-26)\n\n New:\n - New test: Passwordless Solaris accounts test [AUTH-9254]\n - New test: AFICK file integrity [FINT-4310]\n - New test: AIDE file integrity [FINT-4314]\n - New test: Osiris file integrity [FINT-4318]\n - New test: Samhain file integrity [FINT-4322]\n - New test: Tripwire file integrity [FINT-4326]\n - New tests: NIS and NIS+ authentication test [AUTH-9240/42]\n - Initial support added for AFICK, AIDE, Osiris, Samhain, Tripwire\n\n Changes:\n - Changed text of grsecurity test [RBAC-6272]\n - Optimized FreeBSD boot services test [BOOT-5165]\n - Optimized UID 0 test [AUTH-9204]\n - Extended login shells test [AUTH-9218]\n - PID file message extended and small output improvement\n - A log entry will be written when PID files are removed\n - Added operating system name to log file when a test is skipped\n - Added file available check when using --view-manpage\n - Most program variables are initialized now for future additions\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.9 (2008-08-09)\n\n New:\n - New test: AppArmor framework check [MACF-6204]\n - New test: FreeBSD boot loader test [BOOT-5124]\n - New test: PHP option register_globals [PHP-2368]\n - New test: Promiscuous network interfaces (Linux) [NETW-3015]\n - Report option 'bootloader' added to several tests\n - Added readlink binary check\n\n Changes:\n - Extended file check (IsWorldWritable) for symlinks\n - Show result if no default gateway is found [NETW-3001]\n - Added /usr/local/etc to sudoers test [AUTH-9250]\n - Improved FreeBSD banner output [BANN-7113]\n - Removed incorrect line at promiscuous interface test [NETW-3014]\n - Fix: Show only once the GRUB test output [BOOT-5121]\n - Fix: Typo in NTP test [TIME-3104]\n - Fix: Skip NTP test in /etc/cron.d if empty [TIME-3104]\n - Fix: Initialize values when performing an update check without connection\n - Fix: Solaris id function has been fixed\n - Disabled FreeBSD double packages tests, due minor issues [PKGS-7303]\n - Changed LDAP/MySQL running states [LDAP-2219] [DBS-1804]\n - Replaced ifconfig calls with IFCONFIGBINARY\n - Renamed tests_auditing to tests_mac_frameworks\n - Several tests improved with extended logging\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.8 (2008-07-16)\n\n New:\n - Mac OS X support extended and new options added\n\n Changes:\n - Extended default profile\n - Improved several screen output lines\n - User ID check improved, so it works better with older Solaris versions\n - Hostname in output and reports will contain only host now, not FQDN\n - Added extra php.ini locations to tests_php\n - Replaced 'ps' in tests with PSBINARY value for better support\n - Added output to zones test [VIRT-1902]\n - Updated description [AUTH-9218]\n - Extended ntp daemon/ntpdate check [TIME-3104]\n - Added suggestion to bootable scripts check [BOOT_5184]\n - Bugfix and improvement for FreeBSD portsclean test [PKGS-7348]\n - Added Mac OS support to MAC address gathering test [NETW-3006]\n - Added MAC OS support to inet and inet6 addresses test [NETW-3008]\n - Extended PHP expose_php test to support additional options [PHP-2372]\n - Improved LDAP test so it skips correctly on Mac OS AUTH-9238]\n - Bugfix: MySQL status check gave incorrect output [DBS-1804]\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.7 (2008-06-28)\n\n New:\n - New test: check for unused iptables rules [FIRE-4513]\n - New test: checking for dead and zombie processes [PROC-3612]\n - New test: checking for heavy IO waiting processes [PROC-3614]\n - Initial HP-UX support (untested)\n - Initial AIX support (untested)\n - Added iptables binary check\n - Added dig check, for DNS related tests\n - Added option --no-colors to remove all colors from screen output\n - Added option --reverse-colors for optimizing output at light backgrounds\n   (Konsole, MacOS terminal etc)\n\n Changes:\n - Improved grpck test for SuSE [AUTH-9216]\n - Added dig availability check to DNS test [NETW-2704]\n - Bugfix: Fixed iptables test if the binary is not located in /sbin [FIRE-4512]\n - Bugfix: Improved yum-utils check to display suggestions correctly [PKGS-7384]\n - Bugfix: Fixed prerequisites for grpck test [AUTH-9216]\n - Improved MySQL check [DBS-1804]\n - Changed color at chkconfig boot services test [BOOT-5177]\n - Added missing prerequisites output to portaudit test [PKGS-7382]\n - Test output for FreeBSD mounts (UFS) improved [FILE-6329]\n - Extended OpenLDAP test to avoid finding itself in ps output [LDAP-2219]\n - Several tests have their warning reporting improved\n - Improved SuSE Linux detection\n - Improved syslog-ng detection\n - Adjusted README with link to online (extended) documentation\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.6 (2008-06-19)\n\n New:\n - New test: Check writable startup scripts [BOOT-5184]\n - New test: Syslog-NG consistency check [LOGG-2134]\n - New test: Check yum-utils package and scanning package database [PKGS-7384]\n - New test: Test for empty ruleset when iptables is loaded [FIRE-4512]\n - New test: Check for expired SSL certificates [CRYP-7902]\n - New test: Check for LDAP authentication support [AUTH-9238]\n - New test: Read available crontab/cron files [SCHD-7704]\n - New test: Query Solaris running zones [VIRT-1902]\n - New test: Check availability sudoers file for future tests [AUTH-9250]\n - New test: Query all home directories from passwd file [HOME-9302]\n - Syslog-NG support added (binary and version check)\n - Added new sections: Scheduling, Time and Synchronization, Virtualization\n\n Changes:\n - Extended several tests with suggestions and warnings\n - Extended GRUB test with GRUB2 check [BOOT-5121]\n - Extended iptables firewall test [FIRE-4511]\n - Fixed incorrect variable at Linux kernel config display [KRNL-5728]\n - Fixed display for file system test [FILE-6023]\n - Reassigned some ID's to match others in category\n - Improvement of several logging sections and profile options\n - Assigned ID to Ubuntu security update check\n - Assigned ID to pwck test for Solaris [AUTH-9230]\n - Assigned ID to FreeBSD unused distfiles check [PKGS-7348]\n - Assigned ID to RPM package query test [PKGS-7308]\n - Assigned ID to /tmp sticky bit test [FILE-6362]\n - Assigned ID to old temporary files check [FILE-6354]\n - Assigned ID to passwd ID 0 test [AUTH-9204]\n - Assigned ID to FreeBSD swap partitions [FILE-6332]\n - Assigned ID to FreeBSD swap mount options [FILE-6336]\n - Assigned ID to nameserver tests [NETW-2704 and NETW-2705]\n - Assigned ID to pf consistency check [FIRE-4520]\n - Assigned ID to Postfix configuration check [MAIL-8816]\n - Assigned ID to Postfix banner check [MAIL-8818]\n - Assigned ID to FreeBSD promiscuous port test [NETW-3014]\n - Assigned ID to file permissions check [FILE-7524]\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.5 (2008-06-10)\n\n New:\n - Assigned ID to Apache configuration file test [HTTP-6624]\n - Added pause_between_tests to profile file, to regulate the speed of a scan\n - Assigned ID to dpkg test and solved issue with colon in package names [PKG-7345]\n - Assigned ID to Solaris package test [PKG-7306]\n - New test: which gathers virtual hosts from Apache configuration files [HTTP-6626]\n - New test: read all loaded kernel modules (Linux) [KRNL-5726]\n - New test: query available FreeBSD network interfaces [NETW-3004]\n - New test: query available IPv4 and IPv6 network addresses [NETW-3008]\n - New test: for MAC addresses [NETW-3006]\n - New test: check if a Linux kernel configuration file is available [KRNL-5728]\n - New test: check boot services for Debian/Ubuntu [BOOT-5180]\n - Added Lynx, Nmap, Wget version to log file\n - Added support for Oracle enterprise Linux (Unbreakable Linux)\n - Added new function ReportWarning for better logging to report file\n\n Changes:\n - Improved FreeBSD pkg_info output, logging output and report data [PKG-7302]\n - Changed shell history file test, searching files with maxdepth 1 [HOME-9310]\n - Extended iptables test, to check Linux kernel configuration file [FIRE-4511]\n - Added report warning to promiscuous test [NETW-3014]\n - Fixed yellow color when being used at text display\n - Several logging improvements and cleanups\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.4 (2008-05-31)\n\n New:\n - Added option to disable Lynis upgrade availability test (profile option)\n - Added new option --check-update, to display (update) information\n - Added stub for malware and file permissions database\n - New section 'LDAP Services'\n - Support for OpenLDAP added\n - Place holders for new tests are added\n - Default profile extended\n - [FILE-6023] Added test for Linux ext2, ext3, ext4 file systems\n - [BOOT-5155] Added check for YABOOT boot loader\n\n Changes:\n - [BANN-7119] Improved MOTD banner check\n - Improved Apache tests for SuSE and Debian systems\n - Debian/Ubuntu file tests improved\n - Extended man page\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.3 (2008-05-21)\n\n New:\n - Added security updates check for Fedora, RHEL 5.x, CentOS 5.x\n - Added Linux kernel version check\n - Most stable tests have an unique ID now\n - Skipped tests have their reason to skip logged\n - Added /etc/lynis/plugins to searchable plugin directory targets\n - Added Register() function, to handle tests, prerequisites and counter\n - Added new crypto tests\n - Added profile option \"test_skip_always\" to blacklist a specific test\n\n Changes:\n - Extended default profile location for FreeBSD\n - Extended accounting test to include pacct as well\n - Improved tests from categories: shells\n - Disabled skel tests\n - Several tests log their warnings into the report file now\n - Changed Linux default runlevel test\n - Extended man page\n\n Fixes:\n - Auditor name didn't get logged properly to report file.\n - Changed Debian/Ubuntu kernel update test, so it won't be tested on others\n - Exim test failed, due to using an incorrect variable name\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.2 (2008-05-11)\n\n New:\n - Added memory test for Solaris (tested on OpenSolaris)\n - Password file consistency check for Solaris\n - 32/64 bits OS mode check for Solaris\n - Added Slackware detection\n - Plugin support (see documentation)\n - Added monolithic/modular test for Linux kernels\n\n Changes:\n - Improved LILO test and removed double message\n - Fixed incorrect message when using --help parameter\n - Improved portaudit test (FreeBSD) to show unique packages only\n - Updated man page, FAQ, extended documentation with plugin information\n - Added several php.ini file locations (MacOS X, OpenBSD, OpenSuSE)\n\n ** Special release notes [package/ports]: **\n - Added several default paths to check for usable INCLUDE directory. This\n   should make packaging Lynis easier for downstream package providers.\n - When no profile is set, Lynis will check first /etc/lynis/default.prf,\n   before setting default.prf (in current work directory) as profile to use.\n - New directory added to be installed for future versions: plugins\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.1 (2008-04-13)\n\n New:\n - Added Solaris package manager (pkginfo) to obtain installed packages\n - Added new option to profile to whitelist promiscuous interfaces (if_promisc)\n - Added vulnerable packages check for Debian/Ubuntu\n - Added package database consistency check for Debian/Ubuntu\n\n Changes:\n - Only perform boot.conf check for OpenBSD when running on i386\n - Changed RemovePIDFile to prevent incorrect file presence check (ie on OpenBSD)\n - Better OS detection and display output for Ubuntu systems\n - Improved text alignment (display) and logging\n - Commented out some of the default profile options\n - Updated FAQ, readme, man page\n\n Bug fixes:\n - Added missing space at OS detection function\n - Fixed /etc/group tests to ignore commented lines\n - Fixed sticky bit checking on /tmp, so it won't give incorrect results on\n   SuSE/Debian systems\n\n---------------------------------------------------------------------------------\n\nLynis 1.1.0 (2008-04-09)\n\n New:\n - Added test: default gateway (Linux/BSD)\n - Added boot tasks to report file (boottask)\n - Added vulnerable packages to report file (vulnerable_package)\n\n Changes:\n - Fixed some typos\n - Several improvements in log output\n - Changed display of operating system version (Linux)\n - Fixed PHP check\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.9 (2008-03-24)\n\n New:\n - Added --quiet option (currently not 100% quiet yet)\n - Added a spec file to the project page (see web site)\n - Added small INSTALL document\n\n Changes:\n - Changed check for PHP (php.ini location)\n - Added available shells from /etc/shells to report file\n - Updated man page\n - Fixed option in main help window for --man option\n - Code improvement, splitting up sections to separated files\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.8 (2008-02-10)\n\n New:\n - Added pf filter rule test\n - Added our PID to PID file\n - Added warnings, real users, mount points, total tests to report file\n\n Changes:\n - Changed Apache configuration file test\n - Changed old temporary files check\n - Changed test to include ubuntu security repository\n - Moved UID check to avoid PID creation as non root user\n - Moved most functions to separated files and several code cleanups\n - Improved logging output\n - Extended FreeBSD (Copyright file) test\n - Changed indentation for many tests\n - Changed some typos in notice/warning messages\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.7 (2008-01-28)\n\n New:\n - Test: UFS mount point check (FreeBSD)\n - Test: Check swap partitions (FreeBSD)\n - Test: find old files in /tmp\n - Test: check presence iptables\n - Test: check CPU PAE/NX support (Linux)\n - Added profile options check\n - Added option to skip Debian security repository check (profile option)\n - Support for Red Hat and CentOS\n\n Changes:\n - Changed report log location to /var/log instead of current work directory\n - Changed --help (and -h) to display general help, instead of man page\n - Renamed -man option to --man\n - Extended profile file (see default.prf)\n - Cleaned up code (rewritten several parts of static code to dynamic\n   functions)\n - Added more comments to the program, for curious auditors, developers and\n   users. Also regrouped parts of text and cleaned useless white spaces.\n - General program output improved (spaces, indentation)\n - Logging extended\n - Updated lynis.spec file (contrib)\n - FAQ and README files extended and updated\n\n Bugfixes:\n - Changed postfix banner check (thanks to Henk Bokhoven for reporting)\n - Extended skel directory test, with -A (ls) option to check hidden files\n   (used with most Linux variants)\n\n Development:\n - Added new mirror\n - Updated year number in program and support files\n - Added new function Display, to use indentation within lines\n - Added function RemovePIDFile before some exit routines, to clean up PID file\n - Extracted profile support, parameter support to separated files\n - Created file tests_ports_packages for Ports and Packages\n - Deleted lynis.spec file, since it was not working and will be rewritten later\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.6 (2007-12-26)\n\n New:\n - Added Solaris real users test\n - Added hostname check\n\n Changes:\n - Added chkconfig binary test and changed related services test\n - Added 'xargs' to version checks, to replace unwanted chars\n - Added more breaks to log file.\n - Added sorting to rpm/dpkg listings\n - FAQ extended\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.5 (2007-12-02)\n\n New:\n - Test: unique group names\n - Test: unique group IDs\n - Added check for rpm, chkrootkit and rkhunter binary\n - Added function to cleanup at manual interrupt (INT)\n - Support added to run Lynis as cronjob (--cronjob)\n - Fedora support added\n - Added umask 027, to tighten up file permissions\n\n Changes:\n - Changed FreeBSD ttys test\n - Changed grpck test, to operate in read-only mode\n - Changed Postfix test, to check for mail_name value as well\n - Changed GPL line in script which said GPL v2\n - Extended README\n - Show latest update version, if available, at the end of the screen output\n - Lots of code cleanup (see Development)\n - Some log improvements\n - Changed date notation in changelog to preferred European format (with dots\n   instead of slashes)\n\n Development:\n - New function (ShowResult) to avoid repeating the same result line\n   within the script for standard status values\n - Moved program consts to file (include/consts)\n - Moved functions to file (include/functions)\n - Moved OS detection to file (include/osdetection)\n - Added NEVERBREAK to avoid user input (cronjob support)\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.4 (2007-11-27)\n\n New:\n - Test: query real system users (FreeBSD/Linux)\n - Added PID file usage, to warn for unclean program states.\n - Added SSHd version test\n\n Changes:\n - Updated documentation\n - Changed sticky bit test (/tmp), to skip symlinks\n - Changed /etc/motd test, to skip symlinks\n - More code cleanup\n - Logging extended and improved\n - Screen output slightly changed\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.3 (2007-11-19)\n\n New:\n - Added check for sockstat\n - Test: added test for GRUB and password option\n - Test: query listening ports (sockstat)\n\n Changes:\n - Fixed NTPd check (bug)\n - Extended help for 'double installed package' check (BSD systems, pkg_info)\n - Extended Debian kernel update check\n - Improved OpenBSD support\n - Improved Linux specific detection support (Cobalt, CPU Builders, Debian,\n   E-Smith, Slackware, SuSE/OpenSuSE, Turbo Linux, Yellowdog and others)\n - Improved screen output\n - Extended logging, with status/impact flags\n - [Bugfix] chkconfig test improved\n - [Bugfix] Fixed sticky bit test at Debian\n - Extended documentation and changelog file\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.2 (2007-11-15)\n\n New:\n - Test: Added check for NTP daemon or client\n - Test: file permissions (profile option)\n - Added -Q (--quick) parameter, to run the program without needing user\n   input after every few sections.\n\n Changes:\n - Extended documentation (README file) and performed spell check\n - Improved screen output (colors, parameter handling and display)\n - Cleaned up source code and fixed some bad typos\n - Added much more delimiter lines to logfile\n - Added version numbers to logfile for used binaries/tools\n - Updated list of parameters within Lynis help\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.1 (2007-11-12)\n\n New:\n - Test: check Exim configuration file location\n - Test: added memory check (/proc/meminfo)\n - Test: run grpck to check group files (if available)\n - Test: boot option check for OpenBSD boot loader\n - Test: check if pf (Software: firewall) is active\n - Test: check LILO password\n - Test: check presence of old distfiles (FreeBSD)\n - Added check for binaries: httpd, kldstat, openssl, (s)locate\n - Added version check for: exim, openssl\n - Added -V (--version) parameter, to show version number\n - Added breaks between tests\n\n Changes:\n - [bug] Changed skel directory check\n - Fixed display Apache configuration file\n\n---------------------------------------------------------------------------------\n\nLynis 1.0.0 (2007-11-08)\n\n New:\n - Support for CentOS (Tested: 5 Final)\n - Support for Debian (Tested: 4.0)\n - Support for FreeBSD (Tested: 6.2)\n - Support for Mac OS X (Tested: 10.4)\n - Test: Apache (ServerTokens option)\n - Test: PHP (expose_php option)\n - Test: Postfix (smtpd_banner option)\n - Test: check valid shells\n - Test: query pkg_info/RPM based systems\n - Test: query pkg_info for double installed packages\n - Test: query chkprintcap (FreeBSD)\n - Test: scan binary directories\n - Test: check administrator accounts\n - Test: check permissions /etc/motd\n - Test: read nameservers from /etc/resolv.conf\n - Test: query nameservers and test connectivity\n - Test: check promiscuous interfaces (FreeBSD)\n - Test: check sticky bit on /tmp directory\n - Test: check debian.org security branch in /etc/apt/sources.list\n - Test: check kernel update on Debian\n - Test: query default Linux run level\n - Test: query chkconfig to see which services start at boot\n - Test  /etc/COPYRIGHT banner check for FreeBSD\n - Support for program parameters\n - Builtin integrity checks\n - Color enhanced output for readability\n - Support for profiles/templates\n - Report file creation (for reporting/monitoring)\n - Extended logfile creation (with system suggestions)\n - Added lynis.spec file for RPM creation\n - Created project page at website\n - Added documentation (README), ToDo list (TODO)\n - Man page lynis(8)\n\n Changes:\n - No changes\n\n Bugfixes:\n - No bugfixes\n\n\n==========================================================================================\n  Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at github@cisofy.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "\n# Contributions\n\n## Helping out\n\n### Run the latest version from GitHub\nRun the tool in debug mode (use lynis audit system --profile developer.prf) and see if it shows any error.\n\n### Report bugs\nCreate a GitHub issue on the issue tracker.\n\n### Suggest changes (pull request)\nWhen you find something that can be improved, fork the project and create a pull request.\n\n### Translations\nSee the db/languages directory.\n\n\n## Developer Guidelines\n\nTo ensure all pull requests can be easily checked and merged, here are some tips:\n* Your code should work on other platforms running the bourne shell (/bin/sh), not just BASH.\n* Properly document your code where needed. Besides the 'what', focus on explaining the 'why'.\n* Check the log information (lynis.log) of your new test or changed code, so that it provides helpful details for others.\n\n\n## Code Guidelines\n\n### General\nIndentation should be 4 spaces (no tab character).\n\n### Comments\nComments: use # sign followed by a space. When needed, create a comment block.\nBlank lines: allowed, one line maximum.\n\n### Functions\nAll functions use CamelCase to clearly show a difference between shell built-in commands, or external commands.\n\n### Variables\nVariables should be capitalized, with underscore as word separator (e.g. PROCESS_EXISTS=1).\n\n\n## Pull Requests\nWe welcome any contribution to improve Lynis. Contributions to the Lynis project can\nbe submitted as a pull request. The upstream project can be found in our [GitHub repository](https://github.com/CISOfy/lynis).\n\nBy submitting a [Pull Request](https://help.github.com/articles/using-pull-requests/)\nto this repository, you agree that you:\n\n1. Own the contribution that you are providing or have obtained permission from\n   the contribution owner\n\n2. Allow your contribution to be licensed under the license of the target\n   project (GPLv3)\n\n3. Allow your contribution to be freely distributed to the Lynis community\n\n4. Allow the project the [Unlimited Rights](#Unlimited-Rights) to your contribution\n\nIf you have questions regarding development, send us an e-mail at [lynis-dev](mailto:lynis-dev@cisofy.com).\n\n\n## Unlimited Rights\nOur project is licensed under GPLv3. By providing a contribution to the project,\nit will be used for the purpose of the project. Unlimited rights includes the\nrights to use, modify, reproduce, release, perform, display, or disclose computer\nsoftware or computer software documentation in whole or in part, in any manner\nand for any purpose whatsoever, and to have or authorize others to do so.\n\nIf you want to be named in as a contributor in the CONTRIBUTOR file, then include\nthis notation in your pull request. Preferred format: Full Name, and your e-mail\naddress).\n\n"
  },
  {
    "path": "CONTRIBUTORS.md",
    "content": "# Lynis - CONTRIBUTORS\n\n==========================================================================================\n\nThe Lynis project is very thankful to the individuals who contributed to the project.\n\n  Want to contribute as well? Here are some suggestions:\n\n  - Create new tests for your favorite software packages\n  - Translate Lynis into your native language\n  - Report (unexpected) screen errors\n  - Share missing results and findings\n  - Check for grammar issues\n\n  See [CONTRIBUTING.md](https://github.com/CISOfy/lynis/blob/master/CONTRIBUTING.md) for more details.\n\n==========================================================================================\n\n\n## Package Maintainers\n\n* Arch Linux            - Levente Polyak\n* Debian / Ubuntu       - Francisco Manuel Garcia Claramonte\n* Fedora / EPEL         - Athmane Madjoudj\n* FreeBSD port          - Lars Engels\n* NetBSD                - Stephen Borrill\n* Slackware             - Eric Hameleers\n* OpenBSD port          - Gonzalo Rodriguez\n\n\n## Special Contributors\n\nThese people made a significant impact to the development of Lynis:\n\n* Michael Boelen, The Netherlands (original author)\n* Alexander Lobodzinski, Germany\n* Bodine Wilson\n* Brian Ginsbach\n* C.J. Collier, US\n* Charlie Heselton, US\n* Dave Vehrs\n* David Marzal Cánovas, Spain\n* Eric Light, New Zealand\n* Kamil Boratyński, Poland\n* Mike Slifcak, US\n* Mikko Lehtisalo, Finland\n* Steve Bosek, France\n* Thomas Siebel, Germany\n* Thomas Sjögren, Sweden\n* Topi Miettinen, Finland\n* Zach Crownover\n\n\n## Translators\n------------------------------------------\n\n* Chinese               - Shawn - citypw (GitHub)\n* Dutch                 - Michael Boelen, mboelen (GitHub)\n* Finnish               - Juha, Newman101 (GitHub)\n* French                - DocEmmetBrown (GitHub)\n* German                - Kai Raven\n* Hebrew                - Dolev Farhi, dolevf (GitHub)\n* Hungarian             - Zoltan Paldi, paldiz (GitHub)\n* Italian               - Stefano Marty, stefanomarty (GitHub)\n* Japanese              - Yukio Takahara, port80takahara (GitHub)\n* Portuguese            - Dayvidson (GitHub)\n* Spanish               - Jesus Christian Cruz Acono, compermisos (GitHub)\n* Swedish               - Peter Carlsson, PCarlsson (GitHub)\n* Turkish               - Orhan Biyiklioglu, biyiklioglu (GitHub)\n\n\nThanks to all people who contributed code and suggestions for over almost a decade!\n\n\n==========================================================================================\n  Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "FAQ",
    "content": "\n================================================================================\n\n  Lynis - Frequently Asked Questions\n\n================================================================================\n\n  Author:                   2007-2013, Michael Boelen (michael.boelen@cisofy.com)\n                            2013-now, CISOfy development team\n  Description:              Security and system auditing tool\n  Web site:                 https://cisofy.com/lynis/\n  GitHub:                   https://github.com/CISOfy/lynis\n  Support address:          lynis-dev@cisofy.com\n  Development:              May 2007 - Now\n  Support:                  See README file and https://cisofy.com/support/\n  Documentation:            See web site, README, FAQ and CHANGELOG file\n\n================================================================================\n\n[+] General\n-------------------------------\n\n  Q: I don't understand the program (output), what to do?\n  A: Keep reading this FAQ. Also useful are the README file and the log file\n     (default: /var/log/lynis.log). Or check out the documentation on the\n     website: https://cisofy.com/support/\n\n  Q: I can't find any configuration file for Lynis, where is it?\n  A: Lynis uses profiles. A profile is similar to a configuration file and\n     determines how a security scan should be performed. Profiles are usually\n     stored in /etc/lynis or can be found using 'lynis show profiles'.\n\n  Q: My version is outdated, what can I do to upgrade?\n     Check out the upgrade guide: https://cisofy.com/documentation/lynis/upgrading/\n\n  Q: Why is there no port/package for my operating system?\n  A: Because there is no maintainer for it yet. If you have the time to keep\n     the port/package current for your preferred operating system, let us know.\n\n  Q: What to do with the report files?\n  A: The output could be used for monitoring (baseline checks). For users of the\n     Lynis Enterprise Suite, they will be used to upload data.\n\n\n\n[+] Bugs or issues\n-------------------------------\n  Q: Where can I report an issue or bug?\n  A: GitHub, or use the developer e-mail address lynis-dev@cisofy.com\n\n\n\n[+] Usage problems\n-------------------------------\n  Q: Lynis hangs while testing the group files (grpck)\n  A: Run the grpck command manually. It will most likely need user input, to\n     repair incorrect groups.\n\n  Q: Lynis doesn't display all messages on a white background\n  A: White text is used for general (and important) messages. Most terminals\n     have a dark background, so it gives extra attention to the message. However\n     if you have a white background (for example Mac OS X), you can run Lynis\n     with --no-colors to strip colors or --reverse-colors to reverse the color\n     scheme. Another option is to change your terminal colors within Mac OS.\n\n  Q: Some tests take very long to finish, what to do?\n  A: Use a second console (or connection) and check the output of ps/lsof etc,\n     to see the status of the active subroutine. If a specific test hangs for a\n     very long time, try to kill that specific process (ie grpck) and see if\n     Lynis continues. Afterwards, run the command manually to see the cause.\n     Check the log file for additional information. Usually the last few lines\n     will indicate what test is stuck.\n\n  Q: When running Lynis, it shows me the usage help even while using correct\n     parameters, why?\n  A: This can happen with alternative shells. Try using a different shell to\n     invoke Lynis (example: bash lynis audit system).\n\n  Q: One or more tests are giving incorrect output. How to solve that?\n  A: Check the log file. If that also has incorrect data, let us know via GitHub\n     or use the developer e-mail address.\n\n  Q: The program takes long to complete and also uses too much resources. Can it\n     be tuned?\n  A: The time it takes to complete depends on the amount of tests to run.\n     However the resources it take can be slightly lowered by increasing the\n     pause_between_tests profile option. Keep in mind this increases the total\n     length of the scan to complete.\n\n\n\n[+] Network related issues\n-------------------------------\n\n  Q: Lynis reports promiscuous interfaces, but they are needed for normal operation,\n     how can I hide this warning?\n  A: Whitelist the interface in the profile file (if_promisc).\n\n\n================================================================================\n"
  },
  {
    "path": "HAPPY_USERS.md",
    "content": "# Happy users of the Lynis project\n\n## Community\n\nSince 2007, the Lynis project helped many system administrators and security\nprofessionals to scan their systems and perform system hardening. Happy users\nand contributors are the foundation of a healthy project.\n\n\n## Your contribution\n\nAre you also using Lynis? Contribute to the project by let others know:\n1) What you like about the tool\n2) How you use it\n\nYour addition to the guestbook below will help existing and new users learn more\nabout how Lynis can help them.\n\n### How to\n\nCreate a pull request and add your name above the first entry. Thanks!\n\n\n## Our guestbook\n\n\n* YOUR NAME AND STORY\n\n\n* Michael Boelen - September 2019\nThe development of Lynis learned me a lot about Linux and Unix security. It is\ninstalled on all my systems to uncover unexpected configuration issues. The\nvaluable feedback and contributions give me the energy to continue to work on\nits development, even after 12+ years!\n\n* Catalyst.net IT - January 2020\nLynis gave us great insight in to the security state of our systems, as well as where we can improve.\n\n* David Osipov - October 2021\nLynis opened my eyes on Linux security hardening best practices. As a newbie, I learn a lot about Linux system architecture while trying to harden my system.\n"
  },
  {
    "path": "INSTALL",
    "content": "\n================================================================================\n\n  Lynis - Installation instructions\n\n================================================================================\n\n  Author:                   2007-2013, Michael Boelen (michael.boelen@cisofy.com)\n                            2013-now, CISOfy development team\n  Description:              Security and system auditing tool\n  Web site:                 https://cisofy.com\n  Support:                  See 'Support' and https://cisofy.com/support/\n  Documentation:            See web site, README, FAQ and CHANGELOG file\n\n================================================================================\n\n\n[+] Run directly\n-------------------------------\n\n  Lynis can be executed directly (unpack tarball, enter lynis directory).\n\n  # sh lynis\n  or\n  # ./lynis\n\n  Root privileges are preferred for full audits.\n\n\n\n[+] Installation\n-------------------------------\n\n  If you want to install Lynis, see the README file (section: Installation) for\n  more tips about how to install or create a custom package.\n\n  Packages are available via https://packages.cisofy.com\n\n\n\n[+] Documentation\n-------------------------------\n\n  Documentation about Lynis can be found in the man page (man lynis, or\n  lynis --man-page), README file and website. Also the FAQ file covers some\n  often asked questions.\n\n\n================================================================================\n"
  },
  {
    "path": "LICENSE",
    "content": "\n                    GNU GENERAL PUBLIC LICENSE\n                     Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "README",
    "content": "\n================================================================================\n\n  Lynis - README\n\n================================================================================\n\n  Author:                   2007-2013, Michael Boelen\n                            2013-2016, CISOfy\n  Description:              Security and system auditing tool\n  Web site:                 https://cisofy.com/lynis/\n  Development:              May 2007 - Now\n  Support policy:           See section 'Support'\n  Documentation:            See web site, README, FAQ and CHANGELOG file\n\n================================================================================\n\n\n  *** NOTE ***\n\n  The website contains the latest documentation\n\n     See https://cisofy.com/documentation/lynis/\n\n\n\n[+] Introduction\n-------------------------------\n\n  Lynis is an auditing tool which tests and gathers (security) information from\n  Unix based systems. The audience for this tool are security and system\n  auditors, network specialists and system maintainers.\n\n  Some of the (future) features and usage options:\n  - System and security audit checks\n  - Compliance testing\n  - File integrity monitoring\n  - System and file forensics\n  - Usage of templates/baselines (reporting and monitoring)\n  - Extended debugging features\n\n  Everyone is free to use Lynis under the conditions of the GPL v3 license (see\n  LICENSE file).\n\n  ========================\n   Quick facts\n  ========================\n   - Name:      Lynis\n   - Type:      audit, security, hardening, forensics tool\n   - License:   GPL v3\n   - Language:  Shell script\n   - Author:    Michael Boelen, CISOfy\n   - Web site:  https://cisofy.com\n   - Required permissions: root preferred, not needed\n   - Other requirements: write access to /tmp\n\n\n\n[+] Installation\n-------------------------------\n\n  Lynis doesn't have to be installed, so it can be used directly from a\n  (removable) disk. If you want the program to be installed, use one of the\n  following methods:\n\n  - Create a custom directory (ie. /usr/local/lynis) and unpack the tarball\n    (tar xfvz lynis-version.tar.gz) into this directory.\n  - Create a RPM package by using the lynis.spec file (see web site)\n    run 'rpmbuild -ta lynis-version.tar.gz' (= build RPM package)\n    run 'rpm -ivh <filename>' (= install RPM package)\n\n  See online documentation for detailed instructions.\n\n\n\n[+] Supported systems\n-------------------------------\n\n  Since the complexity of auditing different systems and platforms, Lynis is\n  developed on BSD and Linux.\n\n  This tool is tested or confirmed to work with at least:\n  AIX, Linux, FreeBSD, OpenBSD, macOS, Solaris. See the website for the full\n  list of tested operating systems.\n\n\n\n[+] Usage\n-------------------------------\n\n  See online documentation for more information about using Lynis.\n\n\n\n[+] Development and Bugs\n-------------------------------\n\n  Found an issue, or do you have a great idea? Let us know:\n\n  * GitHub - https://github.com/CISOfy/lynis\n  * E-mail - lynis-dev@cisofy.com\n\n  Contributions are appreciated and can be done via GitHub. See CONTRIBUTING.md\n  for more information about how to submit them.\n\n\n[+] Support\n-------------------------------\n\n  Lynis is tested on most common operating systems. The documentation (README,\n  FAQ) and the debugging information (/var/log/lynis.log), should cover most\n  questions and problems. Bugs can be reported via GitHub, or sending an e-mail\n  to the lynis-dev address above.\n\n  Commercial features and support is available via CISOfy. This includes support\n  for compliance testing, a web-based interface, reporting, and more.\n  \n  For more information see https://cisofy.com/lynis-enterprise/ or use the\n  contact details at https://cisofy.com/contact/\n\n\n\n[+] Upgrade to Lynis Enterprise\n-------------------------------\n\n  Individuals and companies which use this software for more than 10 systems, should\n  think about the value of this tool in their job. To support ongoing development on\n  this tool we have a commercial version available. Lynis Enterprise Suite uses\n  Lynis to audit systems, but also provides malware scanning, intrusion detection\n  and has additional guidance. For all features, please see our website:\n  https://cisofy.com/lynis-enterprise/\n\n\n\n[+] Thanks\n-------------------------------\n\n  Thanks to the community for using and supporting open source software.\n  Many comments, bugs/patches and questions are the key to success and ongoing\n  motivation in developing tools like this.\n\n\n\n================================================================================\n"
  },
  {
    "path": "README.md",
    "content": "\n\n[![Linux Security Expert badge](https://badges.linuxsecurity.expert/tools/ranking/lynis.svg)](https://linuxsecurity.expert/tools/lynis/)\n[![Build Status](https://travis-ci.org/CISOfy/lynis.svg?branch=master)](https://travis-ci.org/CISOfy/lynis)\n[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/96/badge)](https://bestpractices.coreinfrastructure.org/projects/96)\n[Documentation]\n\n[Documentation]: https://cisofy.com/documentation/lynis/\n\nDo you like this software? **Star the project** and become a [stargazer](https://github.com/CISOfy/lynis/stargazers).\n\n----\n\n# lynis\n\n> Lynis - Security auditing and hardening tool, for UNIX-based systems.\n\nLynis is a security auditing tool for systems based on UNIX like Linux, macOS, BSD, and others. It performs an **in-depth security scan** and runs on the system itself. The primary goal is to test security defenses and **provide tips for further system hardening**. It will also scan for general system information, vulnerable software packages, and possible configuration issues. Lynis was commonly used by system administrators and auditors to assess the security defenses of their systems. Besides the \"blue team,\" nowadays penetration testers also have Lynis in their toolkit.\n\nWe believe software should be **simple**, **updated on a regular basis**, and **open**. You should be able to trust, understand, and have the option to change the software. Many agree with us, as the software is being used by thousands every day to protect their systems.\n\n## Goals\n\nThe main goals of Lynis include:\n- Automated security auditing\n- Compliance testing (e.g. ISO27001, PCI-DSS, HIPAA)\n- Vulnerability detection\n\nThe software (also) assists with:\n- Configuration and asset management\n- Software patch management\n- System hardening\n- Penetration testing (privilege escalation)\n- Intrusion detection\n\n### Audience\n\nTypical users of the software:\n- System administrators\n- Auditors\n- Security officers\n- Penetration testers\n- Security professionals\n\n## Installation\n\nThere are multiple options available to install Lynis.\n\n### Software package\n\nFor systems running Linux, BSD, and macOS, there is typically a package available. This is the preferred method of obtaining Lynis, as it is quick to install and easy to update. The Lynis project itself also provides [packages](https://packages.cisofy.com/) in RPM or DEB format suitable for systems systems running:\n`CentOS`, `Debian`, `Fedora`, `OEL`, `openSUSE`, `RHEL`, `Ubuntu`, and others.\n\nSome distributions may also have Lynis in their software repository: [![Repology](https://repology.org/badge/tiny-repos/lynis.svg)](https://repology.org/project/lynis/versions)\n\nNote: Some distributions don't provide an up-to-date version. In that case it is better to use the CISOfy software repository, download the tarball from the website, or download the latest GitHub release.\n\n### Git\n\nThe very latest developments can be obtained via git.\n\n1. Clone or download the project files (**no compilation nor installation** is required) ;\n\n        git clone https://github.com/CISOfy/lynis\n\n2. Execute:\n\n        cd lynis && ./lynis audit system\n\nIf you want to run the software as `root` (or sudo), we suggest changing the ownership of the files. Use `chown -R 0:0` to recursively alter the owner and group and set it to user ID `0` (`root`). Otherwise Lynis will warn you about the file permissions. After all, you are executing files owned by a non-privileged user.\n\n\n## Documentation\n\nHave a look at the [Lynis documentation](https://cisofy.com/documentation/lynis/) to learn more about the configuration and usage of Lynis. When you are interested in reading more articles about Linux security, then check out the [Linux security blog](https://linux-audit.com/) named Linux Audit. For some suggestions by Lynis, this is also the source used to learn more about specific findings.\n\n## Customization\n\nIf you want to create your own tests, have a look at the [Lynis software development kit](https://github.com/CISOfy/lynis-sdk).\n\n## Security\n\nWe participate in the [CII best practices](https://www.bestpractices.dev/en/projects/96) badge program of the Linux Foundation.\n\n## Media and Awards\n\nLynis is collecting some awards along the way and we are proud of that.\n\n* 2016\n  * [Best of Open Source Software Awards 2016](http://www.infoworld.com/article/3121251/open-source-tools/bossie-awards-2016-the-best-open-source-networking-and-security-software.html#slide13).\n  * Article by TechRepublic, considering Lynis a \"must-have\" tool: [How to quickly audit a Linux system from the command line](http://www.techrepublic.com/article/how-to-quickly-audit-a-linux-system-from-the-command-line/)\n  * [![ToolsWatch Best Tools (top 10)](https://www.toolswatch.org/badges/toptools/2016.svg)](https://www.toolswatch.org/2017/02/2016-top-security-tools-as-voted-by-toolswatch-org-readers/)\n\n* 2015\n  * [![ToolsWatch Best Tools (second place)](https://www.toolswatch.org/badges/toptools/2015.svg)](https://www.toolswatch.org/2016/02/2015-top-security-tools-as-voted-by-toolswatch-org-readers/)\n  * [Best of Open Source Software Awards 2015](http://www.idgenterprise.com/news/press-release/infoworld-announces-the-2015-best-of-open-source-software-awards/) ([mirror](https://web.archive.org/web/20210313082124/https://www.idg.com/news/infoworld-announces-the-2015-best-of-open-source-software-awards/)).\n\n* 2014\n  * [![ToolsWatch Best Tools (third place)](https://www.toolswatch.org/badges/toptools/2014.svg)](https://www.toolswatch.org/2015/01/2014-top-security-tools-as-voted-by-toolswatch-org-readers/)\n\n* 2013\n  * [![ToolsWatch Best Tools (sixth place)](https://www.toolswatch.org/badges/toptools/2013.svg)](https://www.toolswatch.org/2013/12/2013-top-security-tools-as-voted-by-toolswatch-org-readers/)\n\n## Contribute\n\n> We love contributors.\n\nDo you have something to share? Want to help out with translating Lynis into your own language? Create an issue or pull request on GitHub, or send us an e-mail: lynis-dev@cisofy.com.\n\nMore details can be found in the [Contributors Guide](https://github.com/CISOfy/lynis/blob/master/CONTRIBUTING.md).\n\nYou can also simply contribute to the project by _starring_ the project and show your appreciation that way.\n\nThanks!\n\n## License\n\n> GPLv3\n\n## Enterprise version for companies\n\nThis software component is also part of an enterprise solution and focuses on companies. Same quality, yet with more functionality.\n\nFocus areas include compliance (`PCI DSS`, `HIPAA`, `ISO27001`, and others). The Enterprise version comes with:\n* a web interface;\n* dashboard and reporting;\n* hardening snippets;\n* improvement plan (based on risk);\n* commercial support.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 3.x.x   | :white_check_mark: |\n| 2.x.x   | :white_check_mark: |\n| < 2.x   | :x:                |\n\n## Reporting a Vulnerability\n\nTo report a vulnerability, use security@cisofy.com\n\nSee our [security page](https://cisofy.com/security/) for more details.\n\n## Preferred language\n\nEnglish\n\n## Acknowledgments\n\nhttps://cisofy.com/security/#thanks\n\n## Other\n\nSee the latest 'security.txt' at https://cisofy.com/.well-known/security.txt\n"
  },
  {
    "path": "TODO.md",
    "content": "\n# To Do\n\nThere are always thing to do, right?!\n\nLike to help? See CONTRIBUTING.md for more details.\n\n## Remove deprecated tools\n\nRemove usage of `egrep` and `fgrep`. Replace with `grep` or `grep -E`.\n\n### Rationale:\nThe egrep/fgrep commands are deprecated. Although often linked on Linux distributions, here is an example where `egrep` is missing on an embedded Linux distribution: https://github.com/CISOfy/lynis/issues/1191\n\n[The Open Group Base Specifications Issue 7, 2018 edition](https://pubs.opengroup.org/onlinepubs/9699919799/)\n\n> This grep has been enhanced in an upwards-compatible way to provide the exact functionality of the historical egrep and fgrep commands as well. It was the clear intention of the standard developers to consolidate the three greps into a single command."
  },
  {
    "path": "db/languages/az",
    "content": "ERROR_NO_LICENSE=\"Lisenziya açarı konfiqurasiya edilmeyib\"\nERROR_NO_UPLOAD_SERVER=\"Yükləmə sunucusu konfiqurasiya edilmeyib\"\nGEN_CHECKING=\"Yoxlanır\"\nGEN_CURRENT_VERSION=\"Cari versiya\"\nGEN_DEBUG_MODE=\"Səhv ayıklama rejimi\"\nGEN_INITIALIZE_PROGRAM=\"Proqram koşuluyor\"\nGEN_LATEST_VERSION=\"Son versiya\"\nGEN_PHASE=\"faza\"\nGEN_PLUGINS_ENABLED=\"Konfiqur edilen uzantılar\"\nGEN_UPDATE_AVAILABLE=\"Yeniləmə mövcud\"\nGEN_VERBOSE_MODE=\"Etraflı\"\nGEN_WHAT_TO_DO=\"edilecekler\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Bazı istisnai durumlar və məlumatlar tapıldı\"\nNOTE_EXCEPTIONS_FOUND=\"İstisnalar tapıldı\"\nNOTE_PLUGINS_TAKE_TIME=\"Qeyd: Uzantılar daha ətraflı testlər içermektedir və tamamlanmaları uzun davam edəbilər\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Səlahiyyət lazımlı testlər\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Xususi testlər\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Pis proqram\"\nSECTION_MEMORY_AND_PROCESSES=\"Yaddaş ve prosesler\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"Təsirsiz\"\nSTATUS_DONE=\"Bitdi\"\nSTATUS_ENABLED=\"Təsirli\"\nSTATUS_ERROR=\"Səhv\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"Tapıldı\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"Yox\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"Tapılmadı\"\nSTATUS_NOT_RUNNING=\"Çalışmayıb\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_NO=\"Xeyr\"\nSTATUS_OFF=\"Bağlı\"\nSTATUS_OK=\"Əvət\"\nSTATUS_ON=\"Açıq\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"İşleyib\"\nSTATUS_SKIPPED=\"Atlandı\"\nSTATUS_SUGGESTION=\"Teklif\"\nSTATUS_UNKNOWN=\"Bilinmeyib\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"Xəbərdarlıq\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"Bəli\"\nTEXT_UPDATE_AVAILABLE=\"yeniləmə mövcud\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"qeydləri gönderib kömek eyleyin\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/cn",
    "content": "ERROR_NO_LICENSE=\"没有配置的许可证密钥\"\nERROR_NO_UPLOAD_SERVER=\"没有配置的上传服务器\"\nGEN_CHECKING=\"检查中\"\nGEN_CURRENT_VERSION=\"当前版本\"\nGEN_DEBUG_MODE=\"调试模式\"\nGEN_INITIALIZE_PROGRAM=\"程序初始化中\"\nGEN_LATEST_VERSION=\"最新版本\"\nGEN_PHASE=\"阶段\"\nGEN_PLUGINS_ENABLED=\"插件已开启\"\nGEN_UPDATE_AVAILABLE=\"有可以更新的版本\"\nGEN_VERBOSE_MODE=\"详述模式\"\nGEN_WHAT_TO_DO=\"做什么\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"发现一些异常的事件或者信息\"\nNOTE_EXCEPTIONS_FOUND=\"发现异常\"\nNOTE_PLUGINS_TAKE_TIME=\"注意：插件有更多的测试可能会需要几分钟才能完成\"\nNOTE_SKIPPED_SKIPPED_TESTS_NON_PRIVILEGED=\"因非特权模式而跳过的测试\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"因非特权模式而跳过的测试\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"自定义测试\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"恶意软件\"\nSECTION_MEMORY_AND_PROCESSES=\"内存与进程\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"禁用\"\nSTATUS_DONE=\"完成\"\nSTATUS_ENABLED=\"可用\"\nSTATUS_ERROR=\"错误\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"找到\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"没有\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"没有找到\"\nSTATUS_NOT_RUNNING=\"没有运行\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_NO=\"不是\"\nSTATUS_OFF=\"关闭\"\nSTATUS_OK=\"正常\"\nSTATUS_ON=\"开启\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"运行\"\nSTATUS_SKIPPED=\"跳过\"\nSTATUS_SUGGESTION=\"建议\"\nSTATUS_UNKNOWN=\"未知\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"警告\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"是\"\nTEXT_UPDATE_AVAILABLE=\"有可以更新的版本\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"你可以通过记录日志来帮忙\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/da",
    "content": "ERROR_NO_LICENSE=\"Ingen licensnøgle konfigureret\"\nERROR_NO_UPLOAD_SERVER=\"Ingen upload server konfigureret\"\nGEN_CHECKING=\"Tjekker\"\nGEN_CURRENT_VERSION=\"Nuværende version\"\nGEN_DEBUG_MODE=\"Fejlfindingstilstand\"\nGEN_INITIALIZE_PROGRAM=\"Initialiserer program\"\nGEN_LATEST_VERSION=\"Seneste version\"\nGEN_PHASE=\"Fase\"\nGEN_PLUGINS_ENABLED=\"Plugins aktiverede\"\nGEN_UPDATE_AVAILABLE=\"opdatering tilgængelig\"\nGEN_VERBOSE_MODE=\"Detaljeret tilstand\"\nGEN_WHAT_TO_DO=\"At gøre\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Nogle usædvanlige hændelser eller information var fundet\"\nNOTE_EXCEPTIONS_FOUND=\"Undtagelser fundet\"\nNOTE_PLUGINS_TAKE_TIME=\"Bemærk: plugins har mere omfattende tests og kan tage flere minutter at fuldføre\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Sprang over tests på grund af ikke-privilegeret tilstand\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Brugerdefinerede Tests\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Hukommelse og Processer\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"DEAKTIVERET\"\nSTATUS_DONE=\"FÆRDIG\"\nSTATUS_ENABLED=\"AKTIVERET\"\nSTATUS_ERROR=\"FEJL\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"FUNDET\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"INGEN\"\nSTATUS_NO=\"NEJ\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\nSTATUS_NOT_ENABLED=\"IKKE AKTIVERET\"\nSTATUS_NOT_FOUND=\"IKKE FUNDET\"\nSTATUS_NOT_RUNNING=\"KØRER IKKE\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"FRA\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"TIL\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"KØRER\"\nSTATUS_SKIPPED=\"SPRUNGET OVER\"\nSTATUS_SUGGESTION=\"FORSLAG\"\nSTATUS_UNKNOWN=\"UKENDT\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"ADVARSEL\"\nSTATUS_WEAK=\"SVAG\"\nSTATUS_YES=\"JA\"\nTEXT_UPDATE_AVAILABLE=\"opdatering tilgængelig\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Du kan hjælpe ved at bidrage med din logfil\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/de",
    "content": "ERROR_NO_LICENSE=\"Kein Lizenzschlüssel eingerichtet\"\nERROR_NO_UPLOAD_SERVER=\"Kein Upload-Server eingerichtet\"\nGEN_CHECKING=\"Überprüfung\"\nGEN_CURRENT_VERSION=\"Aktuelle Version\"\nGEN_DEBUG_MODE=\"Debug-Modus\"\nGEN_INITIALIZE_PROGRAM=\"Initialisiere Programm\"\nGEN_LATEST_VERSION=\"Aktuellste Version\"\nGEN_PHASE=\"Phase\"\nGEN_PLUGINS_ENABLED=\"Plugins aktiviert\"\nGEN_UPDATE_AVAILABLE=\"Aktualisierung verfügbar\"\nGEN_VERBOSE_MODE=\"Ausführlicher Modus\"\nGEN_WHAT_TO_DO=\"Was zu tun ist\"\nNOTE_EXCEPTIONS_FOUND=\"Abweichungen gefunden\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Einige außergewöhnliche Ereignisse oder Informationen wurden gefunden\"\nNOTE_PLUGINS_TAKE_TIME=\"Beachte: Plugins beinhalten eingehendere Tests und können mehrere Minuten benötigen, bis sie abgeschlossen sind\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Übersprungene Tests aufgrund nicht privilegiertem Modus\"\nSECTION_ACCOUNTING=\"Accounting\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Banner und Identifizierung\"\nSECTION_BASICS=\"Grundlegendes\"\nSECTION_BOOT_AND_SERVICES=\"Systemstart und Dienste\"\nSECTION_CONTAINERS=\"Container\"\nSECTION_CRYPTOGRAPHY=\"Kryptographie\"\nSECTION_CUSTOM_TESTS=\"Benutzerdefinierte Tests\"\nSECTION_DATA_UPLOAD=\"Daten hochladen\"\nSECTION_DATABASES=\"Datenbanken\"\nSECTION_DOWNLOADS=\"Downloads\"\nSECTION_EMAIL_AND_MESSAGING=\"Software: E-Mail und Messaging\"\nSECTION_FILE_INTEGRITY=\"Software: Dateintegrität\"\nSECTION_FILE_PERMISSIONS=\"Dateiberechtigungen\"\nSECTION_FILE_SYSTEMS=\"Dateisysteme\"\nSECTION_FIREWALLS=\"Software: Firewalls\"\nSECTION_GENERAL=\"Allgemein\"\nSECTION_HARDENING=\"Härtung\"\nSECTION_HOME_DIRECTORIES=\"Heimatverzeichnisse\"\nSECTION_IMAGE=\"Image\"\nSECTION_INITIALIZING_PROGRAM=\"Initialisiere Programm\"\nSECTION_INSECURE_SERVICES=\"Unsichere Dienste\"\nSECTION_KERNEL=\"Kernel\"\nSECTION_KERNEL_HARDENING=\"Kernelhärtung\"\nSECTION_LDAP_SERVICES=\"LDAP Dienste\"\nSECTION_LOGGING_AND_FILES=\"Logs und Logdateien\"\nSECTION_MALWARE=\"Software: Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Software: Speicher und Prozesse\"\nSECTION_NAME_SERVICES=\"Namensauflösung\"\nSECTION_NETWORKING=\"Netzwerk\"\nSECTION_PERMISSIONS=\"Berechtigungen\"\nSECTION_PORTS_AND_PACKAGES=\"Ports und Pakete\"\nSECTION_PRINTERS_AND_SPOOLS=\"Drucker und Warteschlange\"\nSECTION_PROGRAM_DETAILS=\"Programmdetails\"\nSECTION_SCHEDULED_TASKS=\"Geplante Aufgaben\"\nSECTION_SECURITY_FRAMEWORKS=\"Sicherheitsframeworks\"\nSECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"SNMP Unterstützung\"\nSECTION_SOFTWARE=\"Software\"\nSECTION_SQUID_SUPPORT=\"Squid\"\nSECTION_SSH_SUPPORT=\"SSH\"\nSECTION_STORAGE=\"Speicher\"\nSECTION_SYSTEM_INTEGRITY=\"Software: Systemintegrität\"\nSECTION_SYSTEM_TOOLING=\"Software: Systemwerkzeuge\"\nSECTION_SYSTEM_TOOLS=\"Systemwerkzeuge\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Zeit und Zeitsynchronisierung\"\nSECTION_USB_DEVICES=\"USB Geräte\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Benutzer, Gruppen und Authentifizierung\"\nSECTION_VIRTUALIZATION=\"Virtualisierung\"\nSECTION_WEBSERVER=\"Software: Webserver\"\nSTATUS_ACTIVE=\"AKTIV\"\nSTATUS_CHECK_NEEDED=\"ÜBERPRÜFUNG BENÖTIGT\"\nSTATUS_DEBUG=\"DEBUG\"\nSTATUS_DEFAULT=\"STANDARD\"\nSTATUS_DIFFERENT=\"UNTERSCHIEDLICH\"\nSTATUS_DISABLED=\"DEAKTIVIERT\"\nSTATUS_DONE=\"FERTIG\"\nSTATUS_ENABLED=\"AKTIVIERT\"\nSTATUS_ERROR=\"FEHLER\"\nSTATUS_EXPOSED=\"VERWUNDBAR\"\nSTATUS_FAILED=\"FEHLERHAFT\"\nSTATUS_FILES_FOUND=\"DATEIEN GEFUNDEN\"\nSTATUS_FOUND=\"GEFUNDEN\"\nSTATUS_HARDENED=\"GEHÄRTET\"\nSTATUS_INSTALLED=\"INSTALLIERT\"\nSTATUS_LOCAL_ONLY=\"NUR LOKAL\"\nSTATUS_MEDIUM=\"MITTEL\"\nSTATUS_NO=\"NEIN\"\nSTATUS_NO_UPDATE=\"KEINE AKTUALISIERUNG\"\nSTATUS_NON_DEFAULT=\"NICHT STANDARD\"\nSTATUS_NONE=\"NICHTS\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\nSTATUS_NOT_CONFIGURED=\"NICHT KONFIGURIERT\"\nSTATUS_NOT_DISABLED=\"NICHT DEAKTIVIERT\"\nSTATUS_NOT_ENABLED=\"NICHT AKTIVIERT\"\nSTATUS_NOT_FOUND=\"NICHT GEFUNDEN\"\nSTATUS_NOT_RUNNING=\"LÄUFT NICHT\"\nSTATUS_OFF=\"AUS\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"AN\"\nSTATUS_PARTIALLY_HARDENED=\"TEILWEISE GEHÄRTET\"\nSTATUS_PROTECTED=\"GESCHÜTZT\"\nSTATUS_RUNNING=\"LÄUFT\"\nSTATUS_SKIPPED=\"ÜBERSPRUNGEN\"\nSTATUS_SUGGESTION=\"VORSCHLAG\"\nSTATUS_UNKNOWN=\"UNBEKANNT\"\nSTATUS_UNSAFE=\"UNSICHER\"\nSTATUS_UPDATE_AVAILABLE=\"AKTUALISIERUNG VERFÜGBAR\"\nSTATUS_WARNING=\"WARNUNG\"\nSTATUS_WEAK=\"SCHWACH\"\nSTATUS_YES=\"JA\"\nTEXT_UPDATE_AVAILABLE=\"Aktualisierung verfügbar\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Sie können durch Übermittlung Ihrer Logdatei helfen\"\nSECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/en",
    "content": "ERROR_NO_LICENSE=\"No license key configured\"\nERROR_NO_UPLOAD_SERVER=\"No upload server configured\"\nGEN_CHECKING=\"Checking\"\nGEN_CURRENT_VERSION=\"Current version\"\nGEN_DEBUG_MODE=\"Debug mode\"\nGEN_INITIALIZE_PROGRAM=\"Initializing program\"\nGEN_LATEST_VERSION=\"Latest version\"\nGEN_PHASE=\"phase\"\nGEN_PLUGINS_ENABLED=\"Plugins enabled\"\nGEN_UPDATE_AVAILABLE=\"update available\"\nGEN_VERBOSE_MODE=\"Verbose mode\"\nGEN_WHAT_TO_DO=\"What to do\"\nNOTE_EXCEPTIONS_FOUND=\"Exceptions found\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Some exceptional events or information was found\"\nNOTE_PLUGINS_TAKE_TIME=\"Note: plugins have more extensive tests and may take several minutes to complete\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Skipped tests due to non-privileged mode\"\nSECTION_ACCOUNTING=\"Accounting\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\nSECTION_BASICS=\"Basics\"\nSECTION_BOOT_AND_SERVICES=\"Boot and services\"\nSECTION_CONTAINERS=\"Containers\"\nSECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Custom tests\"\nSECTION_DATA_UPLOAD=\"Data upload\"\nSECTION_DATABASES=\"Databases\"\nSECTION_DOWNLOADS=\"Downloads\"\nSECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\nSECTION_FILE_INTEGRITY=\"Software: file integrity\"\nSECTION_FILE_PERMISSIONS=\"File Permissions\"\nSECTION_FILE_SYSTEMS=\"File systems\"\nSECTION_FIREWALLS=\"Software: firewalls\"\nSECTION_GENERAL=\"General\"\nSECTION_HARDENING=\"Hardening\"\nSECTION_HOME_DIRECTORIES=\"Home directories\"\nSECTION_IMAGE=\"Image\"\nSECTION_INITIALIZING_PROGRAM=\"Initializing program\"\nSECTION_INSECURE_SERVICES=\"Insecure services\"\nSECTION_KERNEL=\"Kernel\"\nSECTION_KERNEL_HARDENING=\"Kernel Hardening\"\nSECTION_LDAP_SERVICES=\"LDAP Services\"\nSECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Software: Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Memory and Processes\"\nSECTION_NAME_SERVICES=\"Name services\"\nSECTION_NETWORKING=\"Networking\"\nSECTION_PERMISSIONS=\"Permissions\"\nSECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\nSECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\nSECTION_PROGRAM_DETAILS=\"Program Details\"\nSECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\nSECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\nSECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"SNMP Support\"\nSECTION_SOFTWARE=\"Software\"\nSECTION_SQUID_SUPPORT=\"Squid Support\"\nSECTION_SSH_SUPPORT=\"SSH Support\"\nSECTION_STORAGE=\"Storage\"\nSECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\nSECTION_SYSTEM_TOOLING=\"Software: System tooling\"\nSECTION_SYSTEM_TOOLS=\"System tools\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\nSECTION_USB_DEVICES=\"USB Devices\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\nSECTION_VIRTUALIZATION=\"Virtualization\"\nSECTION_WEBSERVER=\"Software: webserver\"\nSECTION_KERBEROS=\"Kerberos\"\nSTATUS_ACTIVE=\"ACTIVE\"\nSTATUS_CHECK_NEEDED=\"CHECK NEEDED\"\nSTATUS_DEBUG=\"DEBUG\"\nSTATUS_DEFAULT=\"DEFAULT\"\nSTATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"DISABLED\"\nSTATUS_DONE=\"DONE\"\nSTATUS_ENABLED=\"ENABLED\"\nSTATUS_ERROR=\"ERROR\"\nSTATUS_EXPOSED=\"EXPOSED\"\nSTATUS_FAILED=\"FAILED\"\nSTATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"FOUND\"\nSTATUS_HARDENED=\"HARDENED\"\nSTATUS_INSTALLED=\"INSTALLED\"\nSTATUS_LOCAL_ONLY=\"LOCAL ONLY\"\nSTATUS_MEDIUM=\"MEDIUM\"\nSTATUS_NO=\"NO\"\nSTATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"NONE\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\nSTATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\nSTATUS_NOT_DISABLED=\"NOT DISABLED\"\nSTATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"NOT FOUND\"\nSTATUS_NOT_RUNNING=\"NOT RUNNING\"\nSTATUS_OFF=\"OFF\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ON\"\nSTATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\nSTATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"RUNNING\"\nSTATUS_SKIPPED=\"SKIPPED\"\nSTATUS_SUGGESTION=\"SUGGESTION\"\nSTATUS_UNKNOWN=\"UNKNOWN\"\nSTATUS_UNSAFE=\"UNSAFE\"\nSTATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"WARNING\"\nSTATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"YES\"\nTEXT_UPDATE_AVAILABLE=\"update available\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"You can help by providing your log file\"\n"
  },
  {
    "path": "db/languages/es",
    "content": "ERROR_NO_LICENSE=\"No se ha configurado una clave de licencia\"\nERROR_NO_UPLOAD_SERVER=\"No se ha configurado un servidor para subidas\"\nGEN_CHECKING=\"Revisando\"\nGEN_CURRENT_VERSION=\"Versión actual\"\nGEN_DEBUG_MODE=\"Modo de depuración\"\nGEN_INITIALIZE_PROGRAM=\"Iniciando la aplicación\"\nGEN_LATEST_VERSION=\"Última versión\"\nGEN_PHASE=\"fase\"\nGEN_PLUGINS_ENABLED=\"Plugins activados\"\nGEN_UPDATE_AVAILABLE=\"Actualización disponible\"\nGEN_VERBOSE_MODE=\"Modo detallado\"\nGEN_WHAT_TO_DO=\"Qué hacer\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Se encontró alguna excepción o evento extraordinario\"\nNOTE_EXCEPTIONS_FOUND=\"Excepciones encontradas\"\nNOTE_PLUGINS_TAKE_TIME=\"Nota: los plugins contienen pruebas más extensivas y toman más tiempo\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Pruebas omitidas, debido a que el modo no privilegiado está activo\"\nSECTION_ACCOUNTING=\"Contabilidad\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Banners e identificación\"\nSECTION_BASICS=\"Básicos\"\nSECTION_BOOT_AND_SERVICES=\"Arranque y servicios\"\nSECTION_CONTAINERS=\"Contenedores\"\nSECTION_CRYPTOGRAPHY=\"Criptografía\"\nSECTION_CUSTOM_TESTS=\"Pruebas personalizadas\"\nSECTION_DATA_UPLOAD=\"Subida de datos\"\nSECTION_DATABASES=\"Bases de datos\"\nSECTION_DOWNLOADS=\"Descargas\"\nSECTION_EMAIL_AND_MESSAGING=\"Software: correo electrónico y mensajería\"\nSECTION_FILE_INTEGRITY=\"Software: integridad de ficheros\"\nSECTION_FILE_PERMISSIONS=\"Permisos de ficheros\"\nSECTION_FILE_SYSTEMS=\"Sistemas de ficheros\"\nSECTION_FIREWALLS=\"Software: firewalls\"\nSECTION_GENERAL=\"General\"\nSECTION_HARDENING=\"Bastionado\"\nSECTION_HOME_DIRECTORIES=\"Directorios de inicio\"\nSECTION_IMAGE=\"Imagen\"\nSECTION_INITIALIZING_PROGRAM=\"Inicializando programa\"\nSECTION_INSECURE_SERVICES=\"Servicios inseguros\"\nSECTION_KERBEROS=\"Kerberos\"\nSECTION_KERNEL_HARDENING=\"Bastionado del kernel\"\nSECTION_KERNEL=\"Kernel\"\nSECTION_LDAP_SERVICES=\"Servicios LDAP\"\nSECTION_LOGGING_AND_FILES=\"Logging y ficheros\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MALWARE=\"Software: Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Memoria y procesos\"\nSECTION_NAME_SERVICES=\"Servicios de nombres\"\nSECTION_NETWORKING=\"Conectividad\"\nSECTION_PERMISSIONS=\"Permisos\"\nSECTION_PORTS_AND_PACKAGES=\"Puertos y paquetes\"\nSECTION_PRINTERS_AND_SPOOLS=\"Impresoras y spools\"\nSECTION_PROGRAM_DETAILS=\"Detalles del programa\"\nSECTION_SCHEDULED_TASKS=\"Tareas programadas\"\nSECTION_SECURITY_FRAMEWORKS=\"Frameworks de seguridad\"\nSECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"Soporte SNMP\"\nSECTION_SOFTWARE=\"Software\"\nSECTION_SQUID_SUPPORT=\"Soporte Squid\"\nSECTION_SSH_SUPPORT=\"Soporte SSH\"\nSECTION_STORAGE=\"Almacenamiento\"\nSECTION_SYSTEM_INTEGRITY=\"Software: Integridad del sistema\"\nSECTION_SYSTEM_TOOLING=\"Software: Herramientas del sistema\"\nSECTION_SYSTEM_TOOLS=\"Herramientas del sistema\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Tiempo y sincronización\"\nSECTION_USB_DEVICES=\"Dispositivos USB\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Usuarios, grupos y autenticación\"\nSECTION_VIRTUALIZATION=\"Virtualización\"\nSECTION_WEBSERVER=\"Software: servidor web\"\nSTATUS_ACTIVE=\"ACTIVO\"\nSTATUS_CHECK_NEEDED=\"NECESITA VERIFICACIÓN\"\nSTATUS_DEBUG=\"DEPURACIÓN\"\nSTATUS_DEFAULT=\"POR DEFECTO\"\nSTATUS_DIFFERENT=\"DIFERENTE\"\nSTATUS_DISABLED=\"DESHABILITADO\"\nSTATUS_DONE=\"HECHO\"\nSTATUS_ENABLED=\"HABILITADO\"\nSTATUS_ERROR=\"ERROR\"\nSTATUS_EXPOSED=\"EXPUESTO\"\nSTATUS_FAILED=\"HA FALLADO\"\nSTATUS_FILES_FOUND=\"ARCHIVOS ENCONTRADOS\"\nSTATUS_FOUND=\"ENCONTRADO\"\nSTATUS_HARDENED=\"BASTIONADO\"\nSTATUS_INSTALLED=\"INSTALADO\"\nSTATUS_LOCAL_ONLY=\"SOLO LOCAL\"\nSTATUS_MEDIUM=\"MEDIO\"\nSTATUS_NO_UPDATE=\"SIN ACTUALIZACIÓN\"\nSTATUS_NO=\"NO\"\nSTATUS_NON_DEFAULT=\"NO POR DEFECTO\"\nSTATUS_NONE=\"NINGUNO\"\nSTATUS_NOT_ACTIVE=\"SIN ACTIVAR\"\nSTATUS_NOT_CONFIGURED=\"NO CONFIGURADO\"\nSTATUS_NOT_DISABLED=\"NO DESHABILITADO\"\nSTATUS_NOT_ENABLED=\"NO HABILITADO\"\nSTATUS_NOT_FOUND=\"NO ENCONTRADO\"\nSTATUS_NOT_RUNNING=\"NO ESTÁ CORRIENDO\"\nSTATUS_OFF=\"APAGADO\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ENCENDIDO\"\nSTATUS_PARTIALLY_HARDENED=\"PARCIALMENTE BASTIONADO\"\nSTATUS_PROTECTED=\"PROTEGIDO\"\nSTATUS_RUNNING=\"CORRIENDO\"\nSTATUS_SKIPPED=\"OMITIDO\"\nSTATUS_SUGGESTION=\"SUGERENCIA\"\nSTATUS_UNKNOWN=\"DESCONOCIDO\"\nSTATUS_UNSAFE=\"INSEGURO\"\nSTATUS_UPDATE_AVAILABLE=\"ACTUALIZACIÓN DISPONIBLE\"\nSTATUS_WARNING=\"PELIGRO\"\nSTATUS_WEAK=\"DÉBIL\"\nSTATUS_YES=\"SÍ\"\nTEXT_UPDATE_AVAILABLE=\"Actualización disponible\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Puedes ayudar compartiendo tu archivo de registro\"\n"
  },
  {
    "path": "db/languages/fi",
    "content": "ERROR_NO_LICENSE=\"Lisenssiavainta ei määritetty\"\nERROR_NO_UPLOAD_SERVER=\"Latauspalvelinta ei määritetty\"\nGEN_CHECKING=\"Tarkastetaan\"\nGEN_CURRENT_VERSION=\"Nykyinen versio\"\nGEN_DEBUG_MODE=\"Vikasietotila\"\nGEN_INITIALIZE_PROGRAM=\"Alustetaan ohjelmaa\"\nGEN_LATEST_VERSION=\"Uusin versio\"\nGEN_PHASE=\"vaihe\"\nGEN_PLUGINS_ENABLED=\"Liitännäiset päällä\"\nGEN_UPDATE_AVAILABLE=\"päivitys saatavilla\"\nGEN_VERBOSE_MODE=\"Puhelias tila\"\nGEN_WHAT_TO_DO=\"Mitä tehdä\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Joitakin poikkeuksellisia tapahtumia tai tietoja löytynyt\"\nNOTE_EXCEPTIONS_FOUND=\"Virheitä löytynyt\"\nNOTE_PLUGINS_TAKE_TIME=\"Huomio: liitännäisillä on kattavampia testejä joiden suorittaminen voi viedä muutaman minuutin\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Testejä jätetty suorittamatta ei-etuoikeutetun tilan vuoksi\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Kustomoidut testit\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Haittaohjelma\"\nSECTION_MEMORY_AND_PROCESSES=\"Muisti ja prosessit\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"EI PÄÄLLÄ\"\nSTATUS_DONE=\"VALMIS\"\nSTATUS_ENABLED=\"PÄÄLLÄ\"\nSTATUS_ERROR=\"VIRHE\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"LÖYTYNYT\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\nSTATUS_NO=\"EI\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"EI MITÄÄN\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"EI LÖYTYNYT\"\nSTATUS_NOT_RUNNING=\"EI OLE KÄYNNISSÄ\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"EI PÄÄLLÄ\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"PÄÄLLÄ\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"KÄYNNISSÄ\"\nSTATUS_SKIPPED=\"OHITETTU\"\nSTATUS_SUGGESTION=\"EHDOTUS\"\nSTATUS_UNKNOWN=\"TUNTEMATON\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"VAROITUS\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"KYLLÄ\"\nTEXT_UPDATE_AVAILABLE=\"päivitys saatavilla\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Voit auttaa toimittamalla lokitiedoston\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/fr",
    "content": "ERROR_NO_LICENSE=\"Pas de clé de licence configurée\"\nERROR_NO_UPLOAD_SERVER=\"Pas de serveur de transfert configuré\"\nGEN_CHECKING=\"Vérification\"\nGEN_CURRENT_VERSION=\"Version actuelle\"\nGEN_DEBUG_MODE=\"mode débug\"\nGEN_INITIALIZE_PROGRAM=\"Initialisation\"\nGEN_LATEST_VERSION=\"Dernière version\"\nGEN_PHASE=\"phase\"\nGEN_PLUGINS_ENABLED=\"Plugins activés\"\nGEN_UPDATE_AVAILABLE=\"mise à jour disponible\"\nGEN_VERBOSE_MODE=\"mode verbeux\"\nGEN_WHAT_TO_DO=\"Que faire\"\nNOTE_EXCEPTIONS_FOUND=\"Exceptions trouvées\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Des événements ou informations exceptionnels ont été trouvés\"\nNOTE_PLUGINS_TAKE_TIME=\"Note : Les plugins ont des tests plus poussés qui peuvent prendre plusieurs minutes\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Tests ignorés faute de privilèges\"\nSECTION_ACCOUNTING=\"Comptes\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Bannières et identification\"\nSECTION_BASICS=\"Basics\"\nSECTION_BOOT_AND_SERVICES=\"Démarrage et services\"\nSECTION_CONTAINERS=\"Conteneurs\"\nSECTION_CRYPTOGRAPHY=\"Cryptographie\"\nSECTION_CUSTOM_TESTS=\"Tests personnalisés\"\nSECTION_DATA_UPLOAD=\"Téléchargement de données\"\nSECTION_DATABASES=\"Bases de données\"\nSECTION_DOWNLOADS=\"Téléchargements\"\nSECTION_EMAIL_AND_MESSAGING=\"Logiciel : Email et messagerie\"\nSECTION_FILE_INTEGRITY=\"Logiciel : Intégrité de fichier\"\nSECTION_FILE_PERMISSIONS=\"Permissions de fichier\"\nSECTION_FILE_SYSTEMS=\"Systèmes de fichier\"\nSECTION_FIREWALLS=\"Logiciel : Pare-feu\"\nSECTION_GENERAL=\"Général\"\nSECTION_HARDENING=\"Hardening\"\nSECTION_HOME_DIRECTORIES=\"Dossiers personnels\"\nSECTION_IMAGE=\"Image\"\nSECTION_INITIALIZING_PROGRAM=\"Initialisation du programme\"\nSECTION_INSECURE_SERVICES=\"Services non sécurisés\"\nSECTION_KERNEL=\"Noyau\"\nSECTION_KERNEL_HARDENING=\"Kernel Hardening\"\nSECTION_LDAP_SERVICES=\"Services LDAP\"\nSECTION_LOGGING_AND_FILES=\"Journalisation et fichiers\"\nSECTION_MALWARE=\"Logiciel : Malveillants\"\nSECTION_MEMORY_AND_PROCESSES=\"Mémoire et processus\"\nSECTION_NAME_SERVICES=\"Services de noms\"\nSECTION_NETWORKING=\"Mise en réseau\"\nSECTION_PERMISSIONS=\"Permissions\"\nSECTION_PORTS_AND_PACKAGES=\"Ports et packages\"\nSECTION_PRINTERS_AND_SPOOLS=\"Imprimantes et serveurs d'impression\"\nSECTION_PROGRAM_DETAILS=\"Détails du programme\"\nSECTION_SCHEDULED_TASKS=\"Tâches planifiées\"\nSECTION_SECURITY_FRAMEWORKS=\"Frameworks de sécurité\"\nSECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"Prise en charge SNMP\"\nSECTION_SOFTWARE=\"Logiciel\"\nSECTION_SQUID_SUPPORT=\"Prise en charge Squid\"\nSECTION_SSH_SUPPORT=\"Prise en charge SSH\"\nSECTION_STORAGE=\"Stockage\"\nSECTION_SYSTEM_INTEGRITY=\"Logiciel : Intégrité du système\"\nSECTION_SYSTEM_TOOLING=\"Logiciel : System tooling\"\nSECTION_SYSTEM_TOOLS=\"Outils système\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Heure et synchronisation\"\nSECTION_USB_DEVICES=\"Périphériques USB\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Utilisateurs, groupes et authentification\"\nSECTION_VIRTUALIZATION=\"Virtualisation\"\nSECTION_WEBSERVER=\"Logiciel : Serveur web\"\nSTATUS_ACTIVE=\"ACTIF\"\nSTATUS_CHECK_NEEDED=\"VÉRIFICATION NÉCESSAIRE\"\nSTATUS_DEBUG=\"DÉBUG\"\nSTATUS_DEFAULT=\"PAR DÉFAUT\"\nSTATUS_DIFFERENT=\"DIFFÉRENT\"\nSTATUS_DISABLED=\"DÉSACTIVÉ\"\nSTATUS_DONE=\"FAIT\"\nSTATUS_ENABLED=\"ACTIVÉ\"\nSTATUS_ERROR=\"ERREUR\"\nSTATUS_EXPOSED=\"EXPOSÉ\"\nSTATUS_FAILED=\"ÉCHOUÉ\"\nSTATUS_FILES_FOUND=\"FICHIERS TROUVÉS\"\nSTATUS_FOUND=\"TROUVÉ\"\nSTATUS_HARDENED=\"RENFORCÉ\"\nSTATUS_INSTALLED=\"INSTALLÉ\"\nSTATUS_LOCAL_ONLY=\"LOCAL SEULEMENT\"\nSTATUS_MEDIUM=\"MOYEN\"\nSTATUS_NO=\"NON\"\nSTATUS_NO_UPDATE=\"PAS DE MISE A JOUR\"\nSTATUS_NON_DEFAULT=\"PAS PAR DÉFAUT\"\nSTATUS_NONE=\"AUCUN\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\nSTATUS_NOT_CONFIGURED=\"NON CONFIGURÉ\"\nSTATUS_NOT_DISABLED=\"NON DESACTIVÉ\"\nSTATUS_NOT_ENABLED=\"NON ACTIVÉ\"\nSTATUS_NOT_FOUND=\"NON TROUVÉ\"\nSTATUS_NOT_RUNNING=\"NON LANCÉ\"\nSTATUS_OFF=\"OFF\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ON\"\nSTATUS_PARTIALLY_HARDENED=\"PARTIELLEMENT RENFORCÉ\"\nSTATUS_PROTECTED=\"PROTÉGÉ\"\nSTATUS_RUNNING=\"EN COURS\"\nSTATUS_SKIPPED=\"IGNORÉ\"\nSTATUS_SUGGESTION=\"SUGGESTION\"\nSTATUS_UNKNOWN=\"INCONNU\"\nSTATUS_UNSAFE=\"RISQUÉ\"\nSTATUS_UPDATE_AVAILABLE=\"MISE A JOUR DISPONIBLE\"\nSTATUS_WARNING=\"AVERTISSEMENT\"\nSTATUS_WEAK=\"FAIBLE\"\nSTATUS_YES=\"OUI\"\nTEXT_UPDATE_AVAILABLE=\"Mise à jour disponible\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Vous pouvez aider en envoyant votre fichier journal\"\nSECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/gr",
    "content": "ERROR_NO_LICENSE=\"No license key configured\"\nERROR_NO_UPLOAD_SERVER=\"No upload server configured\"\nGEN_CHECKING=\"Γίνεται έλεγχος\"\nGEN_CURRENT_VERSION=\"Τρέχουσα έκδοση\"\nGEN_DEBUG_MODE=\"Debug mode\"\nGEN_INITIALIZE_PROGRAM=\"Initializing program\"\nGEN_LATEST_VERSION=\"Τελευταία έκδοση\"\nGEN_PHASE=\"phase\"\nGEN_PLUGINS_ENABLED=\"Οι προσθήκες είναι ενεργοποιημένες\"\nGEN_UPDATE_AVAILABLE=\"διαθέσιμη ενημέρωση\"\nGEN_VERBOSE_MODE=\"Verbose mode\"\nGEN_WHAT_TO_DO=\"Τι να κάνεις\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Εντοπίστηκαν μερικά εξαιρετικά γεγονότα ή πληροφορίες\"\nNOTE_EXCEPTIONS_FOUND=\"Βρέθηκαν Εξαιρέσεις\"\nNOTE_PLUGINS_TAKE_TIME=\"Note: Τα plugins έχουν πιο εκτεταμένες δοκιμές και μπορεί να διαρκέσουν αρκετά λεπτά για να ολοκληρωθούν\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Παράλειψη δοκιμών λόγω μη προνομιακής λειτουργίας\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Προσαρμοσμένες δοκιμές\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Κακόβουλο λογισμικό\"\nSECTION_MEMORY_AND_PROCESSES=\"Μνήμη και διεργασίες\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"DISABLED\"\nSTATUS_DONE=\"DONE\"\nSTATUS_ENABLED=\"ENABLED\"\nSTATUS_ERROR=\"ΣΦΑΛΜΑ\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"ΒΡΕΘΗΚΕ\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"ΚΑΝΕΝΑ\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"ΔΕΝ ΒΡΕΘΗΚΕ\"\nSTATUS_NOT_RUNNING=\"ΔΕΝ ΤΡΕΧΕΙ\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_NO=\"ΟΧΙ\"\nSTATUS_OFF=\"OFF\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ON\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"ΤΡΕΧΕΙ\"\nSTATUS_SKIPPED=\"ΞΕΠΕΡΑΣΤΗΚΕ\"\nSTATUS_SUGGESTION=\"ΠΡΟΤΑΣΗ\"\nSTATUS_UNKNOWN=\"ΑΓΝΩΣΤΟ\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"ΠΡΟΣΟΧΗ\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"ΝΑΙ\"\nTEXT_UPDATE_AVAILABLE=\"διαθέσιμη ενημέρωση\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Μπορείτε να βοηθήσετε παρέχοντας το αρχείο καταγραφής\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/he",
    "content": "ERROR_NO_LICENSE=\"רישיון לא מוגדר\"\nERROR_NO_UPLOAD_SERVER=\"שרת להעלאת קבצים לא מוגדר\"\nGEN_CHECKING=\"בבדיקה\"\nGEN_CURRENT_VERSION=\"גירסא נוכחית\"\nGEN_DEBUG_MODE=\"מצב ניפוי שגיאות\"\nGEN_INITIALIZE_PROGRAM=\"מאתחל תוכנית\"\nGEN_LATEST_VERSION=\"גירסא אחרונה ועדכנית\"\nGEN_PHASE=\"שלב\"\nGEN_PLUGINS_ENABLED=\"פלאגינים מאופשרים\"\nGEN_UPDATE_AVAILABLE=\"עדכון זמין\"\nGEN_VERBOSE_MODE=\"מצב ארכני\"\nGEN_WHAT_TO_DO=\"לביצוע\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"אירועים חריגים או מידע חריג נמצא\"\nNOTE_EXCEPTIONS_FOUND=\"נמצאו אירועים חריגים\"\nNOTE_PLUGINS_TAKE_TIME=\"לידיעה: חלק מהבדיקות יקחו זמן רב יותר מהרגיל\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"מדלג על בדיקה עקב אי פריבילגיות\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"בדיקה מותאמות\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"תוכנה זדונית\"\nSECTION_MEMORY_AND_PROCESSES=\"זיכרון ותהליכים\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"לא זמין\"\nSTATUS_DONE=\"סיום\"\nSTATUS_ENABLED=\"זמין\"\nSTATUS_ERROR=\"שגיאה\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"נמצא\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"אין כלל\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"לא נמצא\"\nSTATUS_NOT_RUNNING=\"לא רץ\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_NO=\"לא\"\nSTATUS_OFF=\"כבוי\"\nSTATUS_OK=\"או קי\"\nSTATUS_ON=\"פועל\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"בהרצה\"\nSTATUS_SKIPPED=\"דולג\"\nSTATUS_SUGGESTION=\"הצעה\"\nSTATUS_UNKNOWN=\"לא ידוע\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"אזהרה\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"כן\"\nTEXT_UPDATE_AVAILABLE=\"עדכון זמין\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"ניתן לעזור על ידי שליחת קובץ הלוג\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/hu",
    "content": "ERROR_NO_LICENSE=\"Nincs licenc kulcs konfigurálva\"\nERROR_NO_UPLOAD_SERVER=\"Nincs feltöltő szerver konfigurálva\"\nGEN_CHECKING=\"Checking\"\nGEN_CURRENT_VERSION=\"Jelenlegi verzió\"\nGEN_DEBUG_MODE=\"Debug mode\"\nGEN_INITIALIZE_PROGRAM=\"Initializing program\"\n#GEN_LATEST_VERSION=\"Latest version\"\nGEN_PHASE=\"szakasz\"\nGEN_PLUGINS_ENABLED=\"Bővitmények engedelyézve\"\nGEN_UPDATE_AVAILABLE=\"frissítés elérhető\"\nGEN_VERBOSE_MODE=\"Verbose mode\"\nGEN_WHAT_TO_DO=\"What to do\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Some exceptional events or information was found\"\nNOTE_EXCEPTIONS_FOUND=\"Exceptions found\"\nNOTE_PLUGINS_TAKE_TIME=\"Note: plugins have more extensive tests and may take several minutes to complete\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Skipped tests due to non-privileged mode\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Egyedi Tesztek\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Memória és Folyamatok\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"LETILTOTT\"\nSTATUS_DONE=\"KÉSZ\"\nSTATUS_ENABLED=\"ENGEDÉLYEZETT\"\nSTATUS_ERROR=\"HIBA\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"FOUND\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NO=\"NEM\"\nSTATUS_NONE=\"NONE\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"NOT FOUND\"\nSTATUS_NOT_RUNNING=\"NOT RUNNING\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"KI\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"BE\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"RUNNING\"\nSTATUS_SKIPPED=\"SKIPPED\"\nSTATUS_SUGGESTION=\"JAVASLAT\"\nSTATUS_UNKNOWN=\"UNKNOWN\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"FIGYELMEZTETÉS\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"IGEN\"\nTEXT_UPDATE_AVAILABLE=\"frissítés elérhető\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"You can help by providing your log file\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/id",
    "content": "ERROR_NO_LICENSE=\"Tidak ada kunci lisensi yang dikonfigurasi\"\nERROR_NO_UPLOAD_SERVER=\"Tidak ada server unggahan yang dikonfigurasi\"\nGEN_CHECKING=\"Memeriksa\"\nGEN_CURRENT_VERSION=\"Versi sekarang\"\nGEN_DEBUG_MODE=\"Debug mode\"\nGEN_INITIALIZE_PROGRAM=\"Inisialisasi program\"\nGEN_LATEST_VERSION=\"Versi terbaru\"\nGEN_PHASE=\"fase\"\nGEN_PLUGINS_ENABLED=\"Plugin diaktifkan\"\nGEN_UPDATE_AVAILABLE=\"update tersedia\"\nGEN_VERBOSE_MODE=\"Verbose mode\"\nGEN_WHAT_TO_DO=\"Apa yang harus dilakukan\"\nNOTE_EXCEPTIONS_FOUND=\"Pengecualian ditemukan\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Beberapa peristiwa atau informasi luar biasa ditemukan\"\nNOTE_PLUGINS_TAKE_TIME=\"Note: plugin memiliki pengujian yang lebih ekstensif dan mungkin memerlukan waktu beberapa menit untuk menyelesaikannya\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Tes yang dilewati karena mode non-istimewa\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Tes kustom\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Software: Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Memory and Processes\"\nSECTION_NAME_SERVICES=\"Name services\"\nSECTION_NETWORKING=\"Networking\"\nSECTION_PERMISSIONS=\"Permissions\"\nSECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\nSECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\nSECTION_PROGRAM_DETAILS=\"Program Details\"\nSECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\nSECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\nSECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"SNMP Support\"\nSECTION_SOFTWARE=\"Software\"\nSECTION_SQUID_SUPPORT=\"Squid Support\"\nSECTION_SSH_SUPPORT=\"SSH Support\"\nSECTION_STORAGE=\"Storage\"\nSECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\nSECTION_SYSTEM_TOOLING=\"Software: System tooling\"\nSECTION_SYSTEM_TOOLS=\"System tools\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\nSECTION_USB_DEVICES=\"USB Devices\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\nSECTION_VIRTUALIZATION=\"Virtualization\"\nSECTION_WEBSERVER=\"Software: webserver\"\nSTATUS_ACTIVE=\"ACTIVE\"\nSTATUS_CHECK_NEEDED=\"CHECK NEEDED\"\nSTATUS_DEBUG=\"DEBUG\"\nSTATUS_DEFAULT=\"DEFAULT\"\nSTATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"DISABLED\"\nSTATUS_DONE=\"DONE\"\nSTATUS_ENABLED=\"ENABLED\"\nSTATUS_ERROR=\"ERROR\"\nSTATUS_EXPOSED=\"EXPOSED\"\nSTATUS_FAILED=\"FAILED\"\nSTATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"FOUND\"\nSTATUS_HARDENED=\"HARDENED\"\nSTATUS_INSTALLED=\"INSTALLED\"\nSTATUS_LOCAL_ONLY=\"LOCAL ONLY\"\nSTATUS_MEDIUM=\"MEDIUM\"\nSTATUS_NO=\"NO\"\nSTATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"NONE\"\nSTATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\nSTATUS_NOT_DISABLED=\"NOT DISABLED\"\nSTATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"NOT FOUND\"\nSTATUS_NOT_RUNNING=\"NOT RUNNING\"\nSTATUS_OFF=\"OFF\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ON\"\nSTATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\nSTATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"RUNNING\"\nSTATUS_SKIPPED=\"SKIPPED\"\nSTATUS_SUGGESTION=\"SUGGESTION\"\nSTATUS_UNKNOWN=\"UNKNOWN\"\nSTATUS_UNSAFE=\"UNSAFE\"\nSTATUS_UPDATE_AVAILABLE=\"UPDATE TERSEDIA\"\nSTATUS_WARNING=\"WARNING\"\nSTATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"YES\"\nTEXT_UPDATE_AVAILABLE=\"update tersedia\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Anda dapat membantu dengan memberikan file log Anda\"\n#SECTION_KERBEROS=\"Kerberos\"\n#STATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n"
  },
  {
    "path": "db/languages/it",
    "content": "ERROR_NO_LICENSE=\"Nessuna chiave di licenza configurata\"\nERROR_NO_UPLOAD_SERVER=\"Nessun server di upload configurato\"\nGEN_CHECKING=\"Controllo\"\nGEN_CURRENT_VERSION=\"Versione corrente\"\nGEN_DEBUG_MODE=\"Modalità Debug\"\nGEN_INITIALIZE_PROGRAM=\"Inizializzando il programma\"\nGEN_LATEST_VERSION=\"Versione ultima\"\nGEN_PHASE=\"fase\"\nGEN_PLUGINS_ENABLED=\"Plugin abilitati\"\nGEN_UPDATE_AVAILABLE=\"aggiornamento disponibile\"\nGEN_VERBOSE_MODE=\"Modalità Verbose\"\nGEN_WHAT_TO_DO=\"Cosa fare\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Sono stati rilevati alcuni eventi o informazioni eccezionali\"\nNOTE_EXCEPTIONS_FOUND=\"Trovate Eccezioni\"\nNOTE_PLUGINS_TAKE_TIME=\"Nota: i plugin sono sottoposti a test più estesi e possono richiedere alcuni minuti per il completamento\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Test saltati a causa della modalità di esecuzione non privilegiata\"\nSECTION_ACCOUNTING=\"Accounting\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Banners e identificazione\"\nSECTION_BASICS=\"Basi\"\nSECTION_BOOT_AND_SERVICES=\"Avvio e servizi\"\nSECTION_CONTAINERS=\"Container\"\nSECTION_CRYPTOGRAPHY=\"Crittografia\"\nSECTION_CUSTOM_TESTS=\"Test su misura (Custom)\"\nSECTION_DATABASES=\"Database\"\nSECTION_DATA_UPLOAD=\"Caricamenti dati\"\nSECTION_DOWNLOADS=\"Scaricamenti\"\nSECTION_EMAIL_AND_MESSAGING=\"Software: e-mail e messaggistica\"\nSECTION_FILE_INTEGRITY=\"Software: integrità file\"\nSECTION_FILE_PERMISSIONS=\"Permessi file\"\nSECTION_FILE_SYSTEMS=\"File system\"\nSECTION_FIREWALLS=\"Software: firewall\"\nSECTION_GENERAL=\"Generale\"\nSECTION_HARDENING=\"Hardening\"\nSECTION_HOME_DIRECTORIES=\"Cartelle home\"\nSECTION_IMAGE=\"Immagine\"\nSECTION_INITIALIZING_PROGRAM=\"Inizializzando il programma\"\nSECTION_INSECURE_SERVICES=\"Service insicuri\"\nSECTION_KERNEL_HARDENING=\"Hardening del kernel\"\nSECTION_KERNEL=\"Kernel\"\nSECTION_LDAP_SERVICES=\"Servizi LDAP\"\nSECTION_LOGGING_AND_FILES=\"Logging e file\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Memoria e Processi\"\nSECTION_NAME_SERVICES=\"Name services\"\nSECTION_NETWORKING=\"Rete\"\nSECTION_PERMISSIONS=\"Permessi\"\nSECTION_PORTS_AND_PACKAGES=\"Ports e pacchetti\"\nSECTION_PRINTERS_AND_SPOOLS=\"Stampanti e code di stampa\"\nSECTION_PROGRAM_DETAILS=\"Dettagli programma\"\nSECTION_SCHEDULED_TASKS=\"Azioni programmate\"\nSECTION_SECURITY_FRAMEWORKS=\"Framework di sicurezza\"\nSECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"Supporto per SNMP\"\nSECTION_SOFTWARE=\"Software\"\nSECTION_SQUID_SUPPORT=\"Supporto per Squid\"\nSECTION_SSH_SUPPORT=\"Supporto per SSH\"\nSECTION_STORAGE=\"Spazio di archiviazione\"\nSECTION_SYSTEM_INTEGRITY=\"Software: integrità del sistema\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\nSECTION_SYSTEM_TOOLS=\"Strumenti di sistema\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Tempo and Sincronizzazione\"\nSECTION_USB_DEVICES=\"Periferiche USB\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Utenti, Gruppi e Authenticazione\"\nSECTION_VIRTUALIZATION=\"Virtualizzazione\"\nSECTION_WEBSERVER=\"Software: webserver\"\nSTATUS_ACTIVE=\"ATTIVO\"\nSTATUS_CHECK_NEEDED=\"CONTROLLO RICHIESTO\"\nSTATUS_DEBUG=\"DEBUG\"\nSTATUS_DEFAULT=\"DEFAULT\"\nSTATUS_DIFFERENT=\"DIFFERENTE\"\nSTATUS_DISABLED=\"DISABILITATO\"\nSTATUS_DONE=\"FATTO\"\nSTATUS_ENABLED=\"ABILITATO\"\nSTATUS_ERROR=\"ERRORE\"\nSTATUS_EXPOSED=\"ESPOSTO\"\nSTATUS_FAILED=\"FALLITO\"\nSTATUS_FILES_FOUND=\"FILE TROVATI\"\nSTATUS_FOUND=\"TROVATO\"\nSTATUS_HARDENED=\"HARDENED\"\nSTATUS_INSTALLED=\"INSTALLATO\"\nSTATUS_LOCAL_ONLY=\"SOLO LOCALE\"\nSTATUS_MEDIUM=\"MEDIO\"\nSTATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"NESSUNO\"\nSTATUS_NO=\"NO\"\nSTATUS_NOT_ACTIVE=\"NON ATTIVO\"\nSTATUS_NOT_CONFIGURED=\"NON CONFIGURATO\"\nSTATUS_NOT_DISABLED=\"NON DISABILITATO\"\nSTATUS_NOT_ENABLED=\"NON ABILITATO\"\nSTATUS_NOT_FOUND=\"NON TROVATO\"\nSTATUS_NOT_RUNNING=\"NON IN ESECUZIONE\"\nSTATUS_NO_UPDATE=\"NESSUN AGGIORNAMENTO\"\nSTATUS_OFF=\"OFF\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ON\"\nSTATUS_PARTIALLY_HARDENED=\"PARZIALMENTE HARDENED\"\nSTATUS_PROTECTED=\"PROTETTO\"\nSTATUS_RUNNING=\"IN ESECUZIONE\"\nSTATUS_SKIPPED=\"SALTATO\"\nSTATUS_SUGGESTION=\"SUGGERIMENTO\"\nSTATUS_UNKNOWN=\"SCONOSCIUTO\"\nSTATUS_UNSAFE=\"NON SICURO\"\nSTATUS_UPDATE_AVAILABLE=\"AGGIORNAMENTO DISPONIBILE\"\nSTATUS_WARNING=\"ATTENZIONE\"\nSTATUS_WEAK=\"DEBOLE\"\nSTATUS_YES=\"SI\"\nTEXT_UPDATE_AVAILABLE=\"aggiornamento disponibile\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Puoi aiutare fornendoci il tuo file di log\"\nSECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/ja",
    "content": "ERROR_NO_LICENSE=\"ライセンスキーが設定されていません\"\nERROR_NO_UPLOAD_SERVER=\"アップロード先のサーバーが設定されていません\"\nGEN_CHECKING=\"チェック中\"\nGEN_CURRENT_VERSION=\"現在のバージョン\"\nGEN_DEBUG_MODE=\"デバッグモード\"\nGEN_INITIALIZE_PROGRAM=\"プログラムを初期化しています\"\nGEN_LATEST_VERSION=\"最新のバージョン\"\nGEN_PHASE=\"フェーズ\"\nGEN_PLUGINS_ENABLED=\"プラグインが有効\"\nGEN_UPDATE_AVAILABLE=\"アップデートが利用可能\"\nGEN_VERBOSE_MODE=\"詳細モード\"\nGEN_WHAT_TO_DO=\"What to do\"\nNOTE_EXCEPTIONS_FOUND=\"例外が見つかりました\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"例外的なイベントや情報が見つかりました\"\nNOTE_PLUGINS_TAKE_TIME=\"注意: プラグインにはより広範なテストがあり、完了までに数分かかる場合があります\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"非特権モードのためテストをスキップしました\"\nSECTION_ACCOUNTING=\"監査\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"バナー\"\nSECTION_BASICS=\"基本\"\nSECTION_BOOT_AND_SERVICES=\"起動とサービス\"\nSECTION_CONTAINERS=\"コンテナー\"\nSECTION_CRYPTOGRAPHY=\"暗号\"\nSECTION_CUSTOM_TESTS=\"カスタムテスト\"\nSECTION_DATABASES=\"データベース\"\nSECTION_DATA_UPLOAD=\"データアップロード\"\n#SECTION_DOWNLOADS=\"Downloads\"\nSECTION_EMAIL_AND_MESSAGING=\"ソフトウェア: メールとメッセージ\"\nSECTION_FILE_INTEGRITY=\"ソフトウェア: ファイル改ざん防止\"\nSECTION_FILE_PERMISSIONS=\"ファイルの権限\"\nSECTION_FILE_SYSTEMS=\"ファイルシステム\"\nSECTION_FIREWALLS=\"ソフトウェア: ファイアウォール\"\nSECTION_GENERAL=\"一般\"\nSECTION_HARDENING=\"堅牢化\"\nSECTION_HOME_DIRECTORIES=\"ホームディレクトリ\"\n#SECTION_IMAGE=\"Image\"\nSECTION_INITIALIZING_PROGRAM=\"プログラムの初期化\"\nSECTION_INSECURE_SERVICES=\"危険なサービス\"\nSECTION_KERBEROS=\"ケルベロス認証\"\nSECTION_KERNEL=\"カーネル\"\nSECTION_KERNEL_HARDENING=\"カーネルの堅牢化\"\nSECTION_LDAP_SERVICES=\"LDAPサービス\"\nSECTION_LOGGING_AND_FILES=\"ログと削除されたファイル\"\nSECTION_MALWARE=\"マルウェア\"\nSECTION_MEMORY_AND_PROCESSES=\"メモリーとプロセス\"\nSECTION_NAME_SERVICES=\"DNS\"\nSECTION_NETWORKING=\"ネットワーク\"\nSECTION_PERMISSIONS=\"権限\"\nSECTION_PORTS_AND_PACKAGES=\"ポートとパッケージ\"\nSECTION_PRINTERS_AND_SPOOLS=\"プリンターとスプール\"\nSECTION_PROGRAM_DETAILS=\"引数\"\nSECTION_SCHEDULED_TASKS=\"定期実行\"\nSECTION_SECURITY_FRAMEWORKS=\"セキュリティーフレームワーク\"\nSECTION_SHELLS=\"シェル\"\nSECTION_SNMP_SUPPORT=\"SNMPサポート\"\nSECTION_SOFTWARE=\"ソフトウェア\"\nSECTION_SQUID_SUPPORT=\"Squidサポート\"\nSECTION_SSH_SUPPORT=\"SSHサポート\"\nSECTION_STORAGE=\"ストレージ\"\nSECTION_SYSTEM_INTEGRITY=\"ソフトウェア: システム改ざん防止\"\nSECTION_SYSTEM_TOOLING=\"ソフトウェア: システム管理\"\nSECTION_SYSTEM_TOOLS=\"システムツール\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"時刻同期\"\nSECTION_USB_DEVICES=\"USBデバイス\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"ユーザー、グループ、認証\"\nSECTION_VIRTUALIZATION=\"仮想化\"\nSECTION_WEBSERVER=\"ソフトウェア: ウェブサーバー\"\nSTATUS_ACTIVE=\"有効\"\nSTATUS_CHECK_NEEDED=\"確認が必要です\"\nSTATUS_DEBUG=\"デバッグ\"\nSTATUS_DEFAULT=\"デフォルト\"\nSTATUS_DIFFERENT=\"不一致\"\nSTATUS_DISABLED=\"無効になっています\"\nSTATUS_DONE=\"完了\"\nSTATUS_ENABLED=\"有効になっています\"\nSTATUS_ERROR=\"エラー\"\n#STATUS_EXPOSED=\"EXPOSED\"\nSTATUS_FAILED=\"失敗しました\"\nSTATUS_FILES_FOUND=\"ファイルが見つかりました\"\nSTATUS_FOUND=\"見つかりました\"\nSTATUS_HARDENED=\"堅牢化されています\"\nSTATUS_INSTALLED=\"インストールされています\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\nSTATUS_NO=\"いいえ\"\nSTATUS_NONE=\"なし\"\nSTATUS_NON_DEFAULT=\"デフォルトではありません\"\nSTATUS_NOT_ACTIVE=\"機能していません\"\nSTATUS_NOT_CONFIGURED=\"構成されていません\"\nSTATUS_NOT_DISABLED=\"無効になっていません\"\nSTATUS_NOT_ENABLED=\"有効になっていません\"\nSTATUS_NOT_FOUND=\"見つかりません\"\nSTATUS_NOT_RUNNING=\"起動していません\"\nSTATUS_NO_UPDATE=\"アップデートなし\"\nSTATUS_OFF=\"オフ\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"オン\"\nSTATUS_PARTIALLY_HARDENED=\"部分的に堅牢化されています\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"動作中\"\nSTATUS_SKIPPED=\"スキップ\"\nSTATUS_SUGGESTION=\"提案あり\"\nSTATUS_UNKNOWN=\"不明\"\n#STATUS_UNSAFE=\"UNSAFE\"\nSTATUS_UPDATE_AVAILABLE=\"アップデート利用可能\"\nSTATUS_WARNING=\"警告\"\nSTATUS_WEAK=\"脆弱\"\nSTATUS_YES=\"はい\"\nTEXT_UPDATE_AVAILABLE=\"アップデート利用可能\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"ログファイルを共有して改善にご協力ください！\""
  },
  {
    "path": "db/languages/ko",
    "content": "ERROR_NO_LICENSE=\"라이선스 키가 없습니다\"\nERROR_NO_UPLOAD_SERVER=\"업로드 서버가 설정되지 않았습니다\"\nGEN_CHECKING=\"확인중입니다\"\nGEN_CURRENT_VERSION=\"현재 버전\"\nGEN_DEBUG_MODE=\"디버그 모드\"\nGEN_INITIALIZE_PROGRAM=\"프로그램을 초기화합니다\"\nGEN_LATEST_VERSION=\"최신 버전\"\nGEN_PHASE=\"phase\"\nGEN_PLUGINS_ENABLED=\"플러그인이 활성화되었습니다\"\nGEN_UPDATE_AVAILABLE=\"업데이트 가능\"\nGEN_VERBOSE_MODE=\"상세 모드\"\nGEN_WHAT_TO_DO=\"할 일\"\nNOTE_EXCEPTIONS_FOUND=\"예외 발견\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"몇 가지 예외 이벤트나 정보가 발견되었습니다\"\nNOTE_PLUGINS_TAKE_TIME=\"참고: 플러그인은 광범위한 테스트를 거치며 완료될 때까지 몇 분의 시간이 소요됩니다\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"비특권 모드로 인해 테스트를 생략했습니다\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"사용자정의 테스트\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"악성코드\"\nSECTION_MEMORY_AND_PROCESSES=\"메모리와 프로세스\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"비활성화됨\"\nSTATUS_DONE=\"완료\"\nSTATUS_ENABLED=\"활성화됨\"\nSTATUS_ERROR=\"에러\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"발견\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\nSTATUS_NO=\"아니오\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"없음\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"발견되지않음\"\nSTATUS_NOT_RUNNING=\"동작하지않음\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"끔\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"켬\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"동작중\"\nSTATUS_SKIPPED=\"생략\"\nSTATUS_SUGGESTION=\"추천\"\nSTATUS_UNKNOWN=\"알수없음\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"경고\"\nSTATUS_WEAK=\"취약\"\nSTATUS_YES=\"예\"\nTEXT_UPDATE_AVAILABLE=\"업데이트 가능\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"로그 파일을 제공하면 도움을 받을 수 있습니다\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/nb-NO",
    "content": "ERROR_NO_LICENSE=\"Ingen lisensnøkkel konfigurert\"\nERROR_NO_UPLOAD_SERVER=\"Ingen server for opplasting konfigurert\"\nGEN_CHECKING=\"Sjekker\"\nGEN_CURRENT_VERSION=\"Gjeldende versjon\"\nGEN_DEBUG_MODE=\"Feilsøkingsmodus\"\nGEN_INITIALIZE_PROGRAM=\"Initialiserer program\"\nGEN_LATEST_VERSION=\"Seneste version\"\nGEN_PHASE=\"fase\"\nGEN_PLUGINS_ENABLED=\"Utvidelse(r) aktivert\"\nGEN_UPDATE_AVAILABLE=\"oppdatering tilgjengelig\"\nGEN_VERBOSE_MODE=\"Utfyllende modus\"\nGEN_WHAT_TO_DO=\"Hva kan gjøres\"\nNOTE_EXCEPTIONS_FOUND=\"Avvik funnet\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Avvikshendelser eller -informasjon er funnet\"\nNOTE_PLUGINS_TAKE_TIME=\"OBS: utvidelser har omfattende tester og kan ta flere minutter å gjennomføre\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Tester utelatt pga manglende rettigheter\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Tilpassede tester\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Skadevare\"\nSECTION_MEMORY_AND_PROCESSES=\"Minne og prosesser\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"DEAKTIVERT\"\nSTATUS_DONE=\"FERDIG\"\nSTATUS_ENABLED=\"AKTIVERT\"\nSTATUS_ERROR=\"FEIL\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"FUNNET\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NO=\"NEI\"\nSTATUS_NONE=\"INGEN\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"IKKE FUNNET\"\nSTATUS_NOT_RUNNING=\"KJØRER IKKE\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"AV\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"PÅ\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"KJØRER\"\nSTATUS_SKIPPED=\"UTELATT\"\nSTATUS_SUGGESTION=\"FORSLAG\"\nSTATUS_UNKNOWN=\"UKJENT\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"ADVARSEL\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"JA\"\nTEXT_UPDATE_AVAILABLE=\"oppdatering tilgjengelig\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Du kan bidra ved å laste opp din loggfil\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/nl",
    "content": "ERROR_NO_LICENSE=\"Geen licentiecode geconfigureerd\"\nERROR_NO_UPLOAD_SERVER=\"Geen upload server geconfigureerd\"\nGEN_CHECKING=\"Zoeken naar\"\nGEN_CURRENT_VERSION=\"Huidige versie\"\nGEN_DEBUG_MODE=\"Debug modus\"\nGEN_INITIALIZE_PROGRAM=\"Programma initialiseren\"\nGEN_LATEST_VERSION=\"Laatste versie\"\nGEN_PHASE=\"fase\"\nGEN_PLUGINS_ENABLED=\"Plugins geactiveerd\"\nGEN_UPDATE_AVAILABLE=\"Update beschikbaar\"\nGEN_VERBOSE_MODE=\"Verbose modus\"\nGEN_WHAT_TO_DO=\"Wat te doen\"\nNOTE_EXCEPTIONS_FOUND=\"Bijzonderheden gevonden\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Enkele bijzondere gebeurtenissen of informatie gevonden\"\nNOTE_PLUGINS_TAKE_TIME=\"Let op: plugins hebben uitgebreidere testen en kunnen daardoor enkele minuten duren\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Overgeslagen testen vanwege beperkte rechten\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Eigen testen\"\n#SECTION_DATABASES=\"Databases\"\nSECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\nSECTION_INITIALIZING_PROGRAM=\"Programma initialiseren\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Kwaadaardige software (malware)\"\nSECTION_MEMORY_AND_PROCESSES=\"Geheugen en Processen\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\nSECTION_SYSTEM_TOOLS=\"Systeem gereedschap\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"UITGESCHAKELD\"\nSTATUS_DONE=\"KLAAR\"\nSTATUS_ENABLED=\"INGESCHAKELD\"\nSTATUS_ERROR=\"FOUT\"\n#STATUS_EXPOSED=\"EXPOSED\"\nSTATUS_FAILED=\"MISLUKT\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"GEVONDEN\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NO=\"NEE\"\nSTATUS_NONE=\"GEEN\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\nSTATUS_NOT_CONFIGURED=\"NIET GECONFIGUREERD\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"NIET GEVONDEN\"\nSTATUS_NOT_RUNNING=\"NIET ACTIEF\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"UIT\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"AAN\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"ACTIEF\"\nSTATUS_SKIPPED=\"OVERGESLAGEN\"\nSTATUS_SUGGESTION=\"SUGGESTIE\"\nSTATUS_UNKNOWN=\"ONBEKEND\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"WAARSCHUWING\"\nSTATUS_WEAK=\"ZWAK\"\nSTATUS_YES=\"JA\"\nTEXT_UPDATE_AVAILABLE=\"update beschikbaar\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Help mee door je logbestand te delen\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/pl",
    "content": "#ERROR_NO_LICENSE=\"No license key configured\"\n#ERROR_NO_UPLOAD_SERVER=\"No upload server configured\"\n#GEN_CHECKING=\"Checking\"\n#GEN_CURRENT_VERSION=\"Current version\"\n#GEN_DEBUG_MODE=\"Debug mode\"\n#GEN_INITIALIZE_PROGRAM=\"Initializing program\"\n#GEN_LATEST_VERSION=\"Latest version\"\n#GEN_PHASE=\"phase\"\n#GEN_PLUGINS_ENABLED=\"Plugins enabled\"\n#GEN_UPDATE_AVAILABLE=\"update available\"\n#GEN_VERBOSE_MODE=\"Verbose mode\"\n#GEN_WHAT_TO_DO=\"What to do\"\n#NOTE_EXCEPTIONS_FOUND_DETAILED=\"Some exceptional events or information was found\"\n#NOTE_EXCEPTIONS_FOUND=\"Exceptions found\"\n#NOTE_PLUGINS_TAKE_TIME=\"Note: plugins have more extensive tests and may take several minutes to complete\"\n#NOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Skipped tests due to non-privileged mode\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\n#SECTION_CUSTOM_TESTS=\"Custom Tests\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\n#SECTION_MALWARE=\"Malware\"\n#SECTION_MEMORY_AND_PROCESSES=\"Memory and Processes\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\n#STATUS_DISABLED=\"DISABLED\"\n#STATUS_DONE=\"DONE\"\n#STATUS_ENABLED=\"ENABLED\"\n#STATUS_ERROR=\"ERROR\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\n#STATUS_FOUND=\"FOUND\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\n#STATUS_NONE=\"NONE\"\n#STATUS_NO=\"NO\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\n#STATUS_NOT_FOUND=\"NOT FOUND\"\n#STATUS_NOT_RUNNING=\"NOT RUNNING\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\n#STATUS_OFF=\"OFF\"\n#STATUS_OK=\"OK\"\n#STATUS_ON=\"ON\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\n#STATUS_RUNNING=\"RUNNING\"\n#STATUS_SKIPPED=\"SKIPPED\"\n#STATUS_SUGGESTION=\"SUGGESTION\"\n#STATUS_UNKNOWN=\"UNKNOWN\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\n#STATUS_WARNING=\"WARNING\"\n#STATUS_WEAK=\"WEAK\"\n#STATUS_YES=\"YES\"\n#TEXT_UPDATE_AVAILABLE=\"update available\"\n#TEXT_YOU_CAN_HELP_LOGFILE=\"You can help by providing your log file\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/pt",
    "content": "\n# Usado o Google Tradutor para traduzir:  https://translate.google.com.br/\n\n\nERROR_NO_LICENSE=\"Nenhuma chave de licença configurada\"\nERROR_NO_UPLOAD_SERVER=\"Nenhum servidor de upload configurado\"\nGEN_CHECKING=\"Verificando\"\nGEN_CURRENT_VERSION=\"Versão atual\"\nGEN_DEBUG_MODE=\"Modo debug\"\nGEN_INITIALIZE_PROGRAM=\"Iniciando o programa\"\nGEN_LATEST_VERSION=\"Última versão\"\nGEN_PHASE=\"Fase\"\nGEN_PLUGINS_ENABLED=\"Plugins habilitados\"\nGEN_UPDATE_AVAILABLE=\"Atualização disponível\"\nGEN_VERBOSE_MODE=\"Modo verbose\"\nGEN_WHAT_TO_DO=\"O que fazer\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Alguns eventos ou informações excepcionais foram encontrados\"\nNOTE_EXCEPTIONS_FOUND=\"Exceptions encontradas\"\nNOTE_PLUGINS_TAKE_TIME=\"Nota: plugins requerem testes mais extensivos e podem levar vários minutos para completar\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Testes ignorados devido ao modo sem privilégios\"\nSECTION_ACCOUNTING=\"Contabilidade\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Banners e identificação\"\nSECTION_BASICS=\"Base\"\nSECTION_BOOT_AND_SERVICES=\"Inicialização e serviços\"\nSECTION_CONTAINERS=\"Containers\"\nSECTION_CRYPTOGRAPHY=\"Criptografia\"\nSECTION_CUSTOM_TESTS=\"Testes personalizados\"\nSECTION_DATABASES=\"Bancos de dados\"\nSECTION_DATA_UPLOAD=\"Carregamento de dados\"\nSECTION_DOWNLOADS=\"Transferências\"\nSECTION_EMAIL_AND_MESSAGING=\"Programas: e-mail e mensagens\"\nSECTION_FILE_INTEGRITY=\"Programas: integridade do arquivo\"\nSECTION_FILE_PERMISSIONS=\"Permissões de arquivo\"\nSECTION_FILE_SYSTEMS=\"Sistemas de arquivos\"\nSECTION_FIREWALLS=\"Programas: firewalls\"\nSECTION_GENERAL=\"Em geral\"\n#SECTION_HARDENING=\"Hardening\"\nSECTION_HOME_DIRECTORIES=\"Diretórios iniciais\"\nSECTION_IMAGE=\"Imagem\"\nSECTION_INITIALIZING_PROGRAM=\"Inicializando programa\"\nSECTION_INSECURE_SERVICES=\"Serviços inseguros\"\nSECTION_KERNEL_HARDENING=\"Hardening do Kernel\"\nSECTION_KERNEL=\"Kernel\"\nSECTION_LDAP_SERVICES=\"Serviços LDAP\"\nSECTION_LOGGING_AND_FILES=\"Registro e arquivos\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Memória e Processos\"\nSECTION_NAME_SERVICES=\"Serviços de nomes\"\nSECTION_NETWORKING=\"Rede\"\nSECTION_PERMISSIONS=\"Permissões\"\nSECTION_PORTS_AND_PACKAGES=\"Portas e pacotes\"\nSECTION_PRINTERS_AND_SPOOLS=\"Impressoras\"\nSECTION_PROGRAM_DETAILS=\"Detalhes do programa\"\nSECTION_SCHEDULED_TASKS=\"Atividades agendadas\"\nSECTION_SECURITY_FRAMEWORKS=\"Estruturas de segurança\"\n#SECTION_SHELLS=\"Shells\"\nSECTION_SNMP_SUPPORT=\"Suporte SNMP\"\nSECTION_SOFTWARE=\"Programas\"\nSECTION_SQUID_SUPPORT=\"Suporte Squid\"\nSECTION_SSH_SUPPORT=\"Suporte SSH\"\nSECTION_STORAGE=\"Armazenamento\"\nSECTION_SYSTEM_INTEGRITY=\"Programas: Integridade do sistema\"\nSECTION_SYSTEM_TOOLING=\"Programas: Ferramentas de sistema\"\nSECTION_SYSTEM_TOOLS=\"Ferramentas do sistema\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Tempo e sincronização\"\nSECTION_USB_DEVICES=\"Dispositivos USB\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Usuários, grupos e autenticação\"\nSECTION_VIRTUALIZATION=\"Virtualização\"\nSECTION_WEBSERVER=\"Programas: Servidor Web\"\nSTATUS_ACTIVE=\"ATIVO\"\nSTATUS_CHECK_NEEDED=\"VERIFICAÇÃO NECESSÁRIA\"\n#STATUS_DEBUG=\"DEBUG\"\nSTATUS_DEFAULT=\"PADRÃO\"\nSTATUS_DIFFERENT=\"DIFERENTE\"\nSTATUS_DISABLED=\"DESABILITADO\"\nSTATUS_DONE=\"FEITO\"\nSTATUS_ENABLED=\"HABILITADO\"\nSTATUS_ERROR=\"ERRO\"\nSTATUS_EXPOSED=\"EXPOSTO\"\nSTATUS_FAILED=\"FALHAR\"\nSTATUS_FILES_FOUND=\"ARQUIVOS ENCONTRADOS\"\nSTATUS_FOUND=\"ENCONTRADO\"\n#STATUS_HARDENED=\"HARDENED\"\nSTATUS_INSTALLED=\"INSTALADO\"\nSTATUS_LOCAL_ONLY=\"SOMENTE LOCAL\"\nSTATUS_MEDIUM=\"MÉDIO\"\nSTATUS_NO=\"NÃO\"\nSTATUS_NON_DEFAULT=\"FORA DO PADRÃO\"\nSTATUS_NONE=\"NENHUM\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\nSTATUS_NOT_CONFIGURED=\"NÃO CONFIGURADO\"\nSTATUS_NOT_DISABLED=\"NÃO DESATIVADO\"\nSTATUS_NOT_ENABLED=\"NÃO HABILITADO\"\nSTATUS_NOT_FOUND=\"NÃO ENCONTRADO\"\nSTATUS_NOT_RUNNING=\"PARADO\"\nSTATUS_NO_UPDATE=\"SEM ATUALIZAÇÃO\"\nSTATUS_OFF=\"DESLIGADO\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"LIGADO\"\nSTATUS_PARTIALLY_HARDENED=\"HARDENED PARCIAL\"\nSTATUS_PROTECTED=\"PROTEGIDO\"\nSTATUS_RUNNING=\"EM EXECUÇÃO\"\nSTATUS_SKIPPED=\"IGNORADO\"\nSTATUS_SUGGESTION=\"SUGESTÃO\"\nSTATUS_UNKNOWN=\"DESCONHECIDO\"\nSTATUS_UNSAFE=\"INSEGURO\"\nSTATUS_UPDATE_AVAILABLE=\"ATUALIZAÇÃO DISPONÍVEL\"\nSTATUS_WARNING=\"ATENÇÃO\"\nSTATUS_WEAK=\"FRACO\"\nSTATUS_YES=\"SIM\"\nTEXT_UPDATE_AVAILABLE=\"Atualização disponível\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Você pode ajudar fornecendo seu arquivo de log\"\nSECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/ru",
    "content": "ERROR_NO_LICENSE=\"ОШИБКА: ЛИЦЕНЗИОННЫЙ КЛЮЧ НЕ НАСТРОЕН\"\nERROR_NO_UPLOAD_SERVER=\"ОШИБКА: ЗАГРУЗОЧНЫЙ СЕРВЕР НЕ НАСТРОЕН\"\nGEN_CHECKING=\"ПРОВЕРКА\"\nGEN_CURRENT_VERSION=\"ТЕКУЩАЯ ВЕРСИЯ\"\nGEN_DEBUG_MODE=\"РЕЖИМ ОТЛАДКИ\"\nGEN_INITIALIZE_PROGRAM=\"ИНИЦИАЛИЗАЦИЯ ПРОГРАММЫ\"\nGEN_LATEST_VERSION=\"ПОСЛЕДНЯЯ ВЕРСИЯ\"\nGEN_PHASE=\"СТАДИЯ\"\nGEN_PLUGINS_ENABLED=\"ПЛАГИНЫ ВКЛЮЧЕНЫ\"\nGEN_UPDATE_AVAILABLE=\"ДОСТУПНО ОБНОВЛЕНИЕ\"\nGEN_VERBOSE_MODE=\"ПОДРОБНЫЙ РЕЖИМ\"\nGEN_WHAT_TO_DO=\"ЧТО СДЕЛАТЬ?\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"БЫЛИ ОБНАРУЖЕНЫ УНИКАЛЬНЫЕ СОБЫТИЯ ИЛИ СВЕДЕНИЯ\"\nNOTE_EXCEPTIONS_FOUND=\"НАЙДЕННЫ ИСКЛЮЧЕНИЯ\"\nNOTE_PLUGINS_TAKE_TIME=\"ПРИМЕЧАНИЕ: ПЛАГИНЫ ИМЕЮТ БОЛЕЕ ОБШИРНЫЕ ТЕСТЫ И МОГУТ ЗАНЯТЬ НЕСКОЛЬКО МИНУТ ДО ЗАВЕРШЕНИЯ\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"ТЕСТЫ ПРОПУЩЕНЫ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ НЕПРЕВЕЛИГИРОВАННОГО РЕЖИМА\"\nSECTION_ACCOUNTING=\"УЧЁТ\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"БАННЕРЫ И ИДЕНТИФИКАТОРЫ\"\nSECTION_BASICS=\"ОСНОВНОЕ\"\nSECTION_BOOT_AND_SERVICES=\"ЗАГРУЗКА И СЕРВИСЫ\"\nSECTION_CONTAINERS=\"КОНТЕЙНЕРЫ\"\nSECTION_CRYPTOGRAPHY=\"КРИПТОГРАФИЯ\"\nSECTION_CUSTOM_TESTS=\"ПОЛЬЗОВАТЕЛЬСКИЕ ТЕСТЫ\"\nSECTION_DATABASES=\"БАЗЫ ДАННЫХ\"\nSECTION_DATA_UPLOAD=\"ОТПРАВКА ДАННЫХ\"\nSECTION_DOWNLOADS=\"ЗАГРУЗКИ\"\nSECTION_EMAIL_AND_MESSAGING=\"ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ: E-MAIL И ОТПРАВКА СООБЩЕНИЙ\"\nSECTION_FILE_INTEGRITY=\"Программное обеспечение: целостность файлов\"\nSECTION_FILE_PERMISSIONS=\"ПРАВА ДОСТУПА К ФАЙЛАМ\"\nSECTION_FILE_SYSTEMS=\"ФАЙЛОВЫЕ СИСТЕМЫ\"\nSECTION_FIREWALLS=\"ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ: FIREWALL\"\nSECTION_GENERAL=\"ОБЩЕЕ\"\nSECTION_HARDENING=\"УСИЛЕНИЕ\"\nSECTION_HOME_DIRECTORIES=\"ДОМАШНИЕ ДИРЕКТОРИИ\"\nSECTION_IMAGE=\"ОБРАЗЫ\"\nSECTION_INITIALIZING_PROGRAM=\"ИНИЦИАЛИЗАЦИЯ ПРОГРАММЫ\"\nSECTION_INSECURE_SERVICES=\"НЕБЕЗОПАСНЫЕ СЕРВИСЫ\"\nSECTION_KERNEL_HARDENING=\"УСИЛЕНИЕ ЯДРА\"\nSECTION_KERNEL=\"ЯДРО\"\nSECTION_LDAP_SERVICES=\"СЕРВИСЫ LDAP\"\nSECTION_LOGGING_AND_FILES=\"ЛОГИРОВАНИЕ И ФАЙЛЫ\"\nSECTION_MALWARE=\"ВРЕДОНОСНОЕ ПО\"\nSECTION_MEMORY_AND_PROCESSES=\"ПАМЯТЬ И ПРОЦЕССОРЫ\"\nSECTION_NAME_SERVICES=\"СЕРВЕРЫ ИМЁН\"\nSECTION_NETWORKING=\"СЕТИ\"\nSECTION_PERMISSIONS=\"ПРАВА ДОСТУПА\"\nSECTION_PORTS_AND_PACKAGES=\"ПАКЕТЫ\"\nSECTION_PRINTERS_AND_SPOOLS=\"ПРИНТЕРЫ И СПУЛЕРЫ\"\nSECTION_PROGRAM_DETAILS=\"ПОДРОБНОСТИ О ПРОГРАММЕ\"\nSECTION_SCHEDULED_TASKS=\"ЗАПЛАНИРОВАННЫЕ ЗАДАЧИ\"\nSECTION_SECURITY_FRAMEWORKS=\"ФРЕЙМВОРКИ\"\nSECTION_SHELLS=\"КОМАНДНЫЕ ОБОЛОЧКИ\"\nSECTION_SNMP_SUPPORT=\"ПОДДЕРЖКА SNMP\"\nSECTION_SOFTWARE=\"ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ\"\nSECTION_SQUID_SUPPORT=\"ПОДДЕРЖКА Squid\"\nSECTION_SSH_SUPPORT=\"ПОДДЕРЖКА SSH\"\nSECTION_STORAGE=\"ХРАНИЛИЩЕ\"\nSECTION_SYSTEM_INTEGRITY=\"ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ: ЦЕЛОСТНОСТЬ СИСТЕМЫ\"\nSECTION_SYSTEM_TOOLING=\"ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ: СИСТЕМНЫЕ ИНСТУРМЕНТЫ\"\nSECTION_SYSTEM_TOOLS=\"СИСТЕМНЫЕ УТИЛИТЫ\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"ВРЕМЯ И ЕГО СИНХРОНИЗАЦИЯ\"\nSECTION_USB_DEVICES=\"USB УСТРОЙСТВА\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"ПОЛЬЗОВАТЕЛИ, ГРУППЫ И АУТЕНТИФИКАЦИЯ\"\nSECTION_VIRTUALIZATION=\"ВИРТУАЛИЗАЦИЯ\"\nSECTION_WEBSERVER=\"ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ: WEB-СЕРВЕРЫ\"\nSTATUS_ACTIVE=\"АКТИВЕН\"\nSTATUS_CHECK_NEEDED=\"ТРЕБУЕТСЯ ПРОВЕРКА\"\nSTATUS_DEBUG=\"ОТЛАДКА\"\nSTATUS_DEFAULT=\"ПО УМОЛЧАНИЮ\"\nSTATUS_DIFFERENT=\"ОТЛИЧАЕТСЯ\"\nSTATUS_DISABLED=\"ОТКЛЮЧЕНО\"\nSTATUS_DONE=\"ЗАВЕРШЕНО\"\nSTATUS_ENABLED=\"ВКЛЮЧЕНО\"\nSTATUS_ERROR=\"ОШИБКА\"\nSTATUS_EXPOSED=\"УЯЗВИМО\"\nSTATUS_FAILED=\"ПРОВАЛЕНО\"\nSTATUS_FILES_FOUND=\"ФАЙЛЫ НАЙДЕНЫ\"\nSTATUS_FOUND=\"Найдено\"\nSTATUS_HARDENED=\"УСИЛЕНО\"\nSTATUS_INSTALLED=\"УСТАНОВЛЕНО\"\nSTATUS_LOCAL_ONLY=\"ТОЛЬКО ЛОКАЛЬНО\"\nSTATUS_MEDIUM=\"СРЕДНИЙ\"\nSTATUS_NON_DEFAULT=\"НЕ ПО УМОЛЧАНИЮ\"\nSTATUS_NONE=\"ОТСУТСТВУЕТ\"\nSTATUS_NOT_ACTIVE=\"НЕ АКТИВЕН\"\nSTATUS_NOT_CONFIGURED=\"НЕ СКОНФИГУРИРОВАНО\"\nSTATUS_NOT_DISABLED=\"НЕ ОТКЛЮЧЕНО\"\nSTATUS_NOT_ENABLED=\"НЕ ВКЛЮЧЕНО\"\nSTATUS_NOT_FOUND=\"НЕ НАЙДЕНО\"\nSTATUS_NOT_RUNNING=\"НЕ ЗАПУЩЕНО\"\nSTATUS_NO_UPDATE=\"ОБНОВЛЕНИЙ НЕТ\"\nSTATUS_NO=\"НЕТ\"\nSTATUS_OFF=\"ВЫКЛЮЧЕНО\"\nSTATUS_OK=\"ОК\"\nSTATUS_ON=\"ВКЛЮЧЕНО\"\nSTATUS_PARTIALLY_HARDENED=\"ЧАСТИЧНО УСИЛЕНО\"\nSTATUS_PROTECTED=\"ЗАЩИЩЕНО\"\nSTATUS_RUNNING=\"ЗАПУЩЕНО\"\nSTATUS_SKIPPED=\"ПРОПУЩЕНО\"\nSTATUS_SUGGESTION=\"ПРЕДЛОЖЕНИЕ\"\nSTATUS_UNKNOWN=\"НЕИЗВЕСТНО\"\nSTATUS_UNSAFE=\"НЕБЕЗОПАСНО\"\nSTATUS_UPDATE_AVAILABLE=\"ДОСТУПНЫ ОБНОВЛЕНИЯ\"\nSTATUS_WARNING=\"ПРЕДУПРЕЖДЕНИЕ\"\nSTATUS_WEAK=\"СЛАБЫЙ\"\nSTATUS_YES=\"ДА\"\nTEXT_UPDATE_AVAILABLE=\"ДОСТУПНО ОБНОВЛЕНИЕ\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"ПОЖАЛУЙСТА, ПОМОГИТЕ НАМ, ОТПРАВИВ ВАШ LOG-ФАЙЛ\"\nSECTION_KERBEROS=\"KERBEROS\"\n"
  },
  {
    "path": "db/languages/se",
    "content": "ERROR_NO_LICENSE=\"Ingen licensnyckel konfigurerad\"\nERROR_NO_UPLOAD_SERVER=\"Ingen uppladdningsserver konfigurerad\"\nGEN_CHECKING=\"Kontrollera\"\nGEN_CURRENT_VERSION=\"Aktuell version\"\nGEN_DEBUG_MODE=\"Debugläge\"\nGEN_INITIALIZE_PROGRAM=\"Initierar program\"\nGEN_LATEST_VERSION=\"Senaste versionen\"\nGEN_PHASE=\"fas\"\nGEN_PLUGINS_ENABLED=\"Plugins aktiverade\"\nGEN_UPDATE_AVAILABLE=\"uppdatering tillgänglig\"\nGEN_VERBOSE_MODE=\"Detaljerat läge\"\nGEN_WHAT_TO_DO=\"Åtgärd\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"En del ovanliga händelser eller uppgifter konstaterades\"\nNOTE_EXCEPTIONS_FOUND=\"Undantag hittade\"\nNOTE_PLUGINS_TAKE_TIME=\"Obs: plugins har mer omfattande tester och kan ta flera minuter att slutföra\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Undantagna tester på grund av icke-privilegierat läge\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Anpassade Tester\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Minne och Processer\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"AVAKTIVERAD\"\nSTATUS_DONE=\"KLAR\"\nSTATUS_ENABLED=\"AKTIVERAD\"\nSTATUS_ERROR=\"FEL\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"HITTAD\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"INGEN\"\nSTATUS_NO=\"NEJ\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"EJ HITTAD\"\nSTATUS_NOT_RUNNING=\"KÖRS INTE\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"AV\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"PÅ\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"KÖRS\"\nSTATUS_SKIPPED=\"ÖVERHOPPAD\"\nSTATUS_SUGGESTION=\"FÖRSLAG\"\nSTATUS_UNKNOWN=\"OKÄND\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"VARNING\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"JA\"\nTEXT_UPDATE_AVAILABLE=\"uppdatering tillgänglig\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Du kan hjälpa till genom att bidra med din loggfil\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/sk",
    "content": "ERROR_NO_LICENSE=\"Nie je nakonfigurovaný licenčný kľúč\"\nERROR_NO_UPLOAD_SERVER=\"Nie je nakonfigurovaný server na nahrávanie\"\nGEN_CHECKING=\"Kontrolujem\"\nGEN_CURRENT_VERSION=\"Aktuálna verzia\"\nGEN_DEBUG_MODE=\"Debug mód\"\nGEN_INITIALIZE_PROGRAM=\"Inicializácia programu\"\nGEN_LATEST_VERSION=\"Posledná verzia\"\nGEN_PHASE=\"fáza\"\nGEN_PLUGINS_ENABLED=\"Zapnuté pluginy\"\nGEN_UPDATE_AVAILABLE=\"aktualizácia k dispozícii\"\nGEN_VERBOSE_MODE=\"Detailný mód\"\nGEN_WHAT_TO_DO=\"Čo robiť\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Vyskytli sa niektoré výnimočné udalosti alebo informácie\"\nNOTE_EXCEPTIONS_FOUND=\"Našli sa výnimky\"\nNOTE_PLUGINS_TAKE_TIME=\"Poznámka: Pluginy majú rozsiahlejšie testy a dokončenie môže trvať niekoľko minút\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Preskočené testy v dôsledku neprivilegovaného režimu\"\n#SECTION_ACCOUNTING=\"Accounting\"\n#SECTION_BANNERS_AND_IDENTIFICATION=\"Banners and identification\"\n#SECTION_BASICS=\"Basics\"\n#SECTION_BOOT_AND_SERVICES=\"Boot and services\"\n#SECTION_CONTAINERS=\"Containers\"\n#SECTION_CRYPTOGRAPHY=\"Cryptography\"\nSECTION_CUSTOM_TESTS=\"Vlastné testy\"\n#SECTION_DATABASES=\"Databases\"\n#SECTION_DATA_UPLOAD=\"Data upload\"\n#SECTION_DOWNLOADS=\"Downloads\"\n#SECTION_EMAIL_AND_MESSAGING=\"Software: e-mail and messaging\"\n#SECTION_FILE_INTEGRITY=\"Software: file integrity\"\n#SECTION_FILE_PERMISSIONS=\"File Permissions\"\n#SECTION_FILE_SYSTEMS=\"File systems\"\n#SECTION_FIREWALLS=\"Software: firewalls\"\n#SECTION_GENERAL=\"General\"\n#SECTION_HARDENING=\"Hardening\"\n#SECTION_HOME_DIRECTORIES=\"Home directories\"\n#SECTION_IMAGE=\"Image\"\n#SECTION_INITIALIZING_PROGRAM=\"Initializing program\"\n#SECTION_INSECURE_SERVICES=\"Insecure services\"\n#SECTION_KERNEL_HARDENING=\"Kernel Hardening\"\n#SECTION_KERNEL=\"Kernel\"\n#SECTION_LDAP_SERVICES=\"LDAP Services\"\n#SECTION_LOGGING_AND_FILES=\"Logging and files\"\nSECTION_MALWARE=\"Malware\"\nSECTION_MEMORY_AND_PROCESSES=\"Pamäť a procesy\"\n#SECTION_NAME_SERVICES=\"Name services\"\n#SECTION_NETWORKING=\"Networking\"\n#SECTION_PERMISSIONS=\"Permissions\"\n#SECTION_PORTS_AND_PACKAGES=\"Ports and packages\"\n#SECTION_PRINTERS_AND_SPOOLS=\"Printers and Spools\"\n#SECTION_PROGRAM_DETAILS=\"Program Details\"\n#SECTION_SCHEDULED_TASKS=\"Scheduled tasks\"\n#SECTION_SECURITY_FRAMEWORKS=\"Security frameworks\"\n#SECTION_SHELLS=\"Shells\"\n#SECTION_SNMP_SUPPORT=\"SNMP Support\"\n#SECTION_SOFTWARE=\"Software\"\n#SECTION_SQUID_SUPPORT=\"Squid Support\"\n#SECTION_SSH_SUPPORT=\"SSH Support\"\n#SECTION_STORAGE=\"Storage\"\n#SECTION_SYSTEM_INTEGRITY=\"Software: System integrity\"\n#SECTION_SYSTEM_TOOLING=\"Software: System tooling\"\n#SECTION_SYSTEM_TOOLS=\"System tools\"\n#SECTION_TIME_AND_SYNCHRONIZATION=\"Time and Synchronization\"\n#SECTION_USB_DEVICES=\"USB Devices\"\n#SECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Users, Groups and Authentication\"\n#SECTION_VIRTUALIZATION=\"Virtualization\"\n#SECTION_WEBSERVER=\"Software: webserver\"\n#STATUS_ACTIVE=\"ACTIVE\"\n#STATUS_CHECK_NEEDED=\"CHECK NEEDED\"\n#STATUS_DEBUG=\"DEBUG\"\n#STATUS_DEFAULT=\"DEFAULT\"\n#STATUS_DIFFERENT=\"DIFFERENT\"\nSTATUS_DISABLED=\"ZABLOKOVANÉ\"\nSTATUS_DONE=\"HOTOVO\"\nSTATUS_ENABLED=\"POVOLENÉ\"\nSTATUS_ERROR=\"CHYBA\"\n#STATUS_EXPOSED=\"EXPOSED\"\n#STATUS_FAILED=\"FAILED\"\n#STATUS_FILES_FOUND=\"FILES FOUND\"\nSTATUS_FOUND=\"NÁJDENÉ\"\n#STATUS_HARDENED=\"HARDENED\"\n#STATUS_INSTALLED=\"INSTALLED\"\n#STATUS_LOCAL_ONLY=\"LOCAL ONLY\"\n#STATUS_MEDIUM=\"MEDIUM\"\n#STATUS_NON_DEFAULT=\"NON DEFAULT\"\nSTATUS_NONE=\"ŽIADNE\"\nSTATUS_NO=\"NIE\"\nSTATUS_NOT_ACTIVE=\"NOT ACTIVE\"\n#STATUS_NOT_CONFIGURED=\"NOT CONFIGURED\"\n#STATUS_NOT_DISABLED=\"NOT DISABLED\"\n#STATUS_NOT_ENABLED=\"NOT ENABLED\"\nSTATUS_NOT_FOUND=\"NENÁJDENÉ\"\nSTATUS_NOT_RUNNING=\"NEBEŽÍ\"\n#STATUS_NO_UPDATE=\"NO UPDATE\"\nSTATUS_OFF=\"VYPNUTÉ\"\nSTATUS_OK=\"OK\"\nSTATUS_ON=\"ZAPNUTÉ\"\n#STATUS_PARTIALLY_HARDENED=\"PARTIALLY HARDENED\"\n#STATUS_PROTECTED=\"PROTECTED\"\nSTATUS_RUNNING=\"BEŽÍ\"\nSTATUS_SKIPPED=\"PRESKOČENÉ\"\nSTATUS_SUGGESTION=\"NÁVRH\"\nSTATUS_UNKNOWN=\"NEZNÁME\"\n#STATUS_UNSAFE=\"UNSAFE\"\n#STATUS_UPDATE_AVAILABLE=\"UPDATE AVAILABLE\"\nSTATUS_WARNING=\"VAROVANIE\"\n#STATUS_WEAK=\"WEAK\"\nSTATUS_YES=\"ÁNO\"\nTEXT_UPDATE_AVAILABLE=\"aktualizácia k dispozícii\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Môžete pomôcť poskytnutím log súboru\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "db/languages/tr",
    "content": "ERROR_NO_LICENSE=\"Lisans anahtarı yapılandırılmadı\"\nERROR_NO_UPLOAD_SERVER=\"Yükleme sunucusu yapılandırılmadı\"\nGEN_CHECKING=\" Denetleniyor\"\nGEN_CURRENT_VERSION=\"Geçerli sürüm\"\nGEN_DEBUG_MODE=\"Hata ayıklama modu\"\nGEN_INITIALIZE_PROGRAM=\"Program başlatılıyor\"\nGEN_LATEST_VERSION=\"En son sürüm\"\nGEN_PHASE=\"evre\"\nGEN_PLUGINS_ENABLED=\"Etkinleştirilen eklentiler\"\nGEN_UPDATE_AVAILABLE=\"güncelleme var\"\nGEN_VERBOSE_MODE=\"Ayrıntılı mod\"\nGEN_WHAT_TO_DO=\"Yapılması gerekenler\"\nNOTE_EXCEPTIONS_FOUND=\"İstisnalar bulundu\"\nNOTE_EXCEPTIONS_FOUND_DETAILED=\"Bazı istisnai olaylar veya bilgiler bulundu\"\nNOTE_PLUGINS_TAKE_TIME=\"Not: eklentiler daha kapsamlı testlere sahiptir ve tamamlanması birkaç dakika sürebilir\"\nNOTE_SKIPPED_TESTS_NON_PRIVILEGED=\"Yetkisiz çalışma nedeniyle atlanan testler\"\nSECTION_ACCOUNTING=\"Hesaplama\"\nSECTION_BANNERS_AND_IDENTIFICATION=\"Afişler ve tanımlama\"\nSECTION_BASICS=\"Temel Bilgiler\"\nSECTION_BOOT_AND_SERVICES=\"Önyükleme ve hizmetler\"\nSECTION_CONTAINERS=\"Konteynerler\"\nSECTION_CRYPTOGRAPHY=\"Kriptografi\"\nSECTION_CUSTOM_TESTS=\"Özel testler\"\nSECTION_DATA_UPLOAD=\"Veri yükleme\"\nSECTION_DATABASES=\"Veri tabanları\"\nSECTION_DOWNLOADS=\"İndirilenler\"\nSECTION_EMAIL_AND_MESSAGING=\"Yazılım: e-posta ve mesajlaşma\"\nSECTION_FILE_INTEGRITY=\"Yazılım: dosya bütünlüğü\"\nSECTION_FILE_PERMISSIONS=\"Dosya izinleri\"\nSECTION_FILE_SYSTEMS=\"Dosya sistemleri\"\nSECTION_FIREWALLS=\"Yazılım: güvenlik duvarları\"\nSECTION_GENERAL=\"Genel\"\nSECTION_HARDENING=\"Sıkılaştırma\"\nSECTION_HOME_DIRECTORIES=\"Ev dizinleri\"\nSECTION_IMAGE=\"Kalıp\"\nSECTION_INITIALIZING_PROGRAM=\"Program başlatılıyor\"\nSECTION_INSECURE_SERVICES=\"Güvensiz hizmetler\"\nSECTION_KERNEL=\"Çekirdek\"\nSECTION_KERNEL_HARDENING=\"Çekirdek Sıkılaştırma\"\nSECTION_LDAP_SERVICES=\"LDAP Hizmetleri\"\nSECTION_LOGGING_AND_FILES=\"Günlük kaydı ve dosyalar\"\nSECTION_MALWARE=\"Yazılım: Kötü Amaçlı Yazılım\"\nSECTION_MEMORY_AND_PROCESSES=\"Bellek ve Süreçler\"\nSECTION_NAME_SERVICES=\"Ad hizmetleri\"\nSECTION_NETWORKING=\"Ağ İletişimi\"\nSECTION_PERMISSIONS=\"İzinler\"\nSECTION_PORTS_AND_PACKAGES=\"Bağlantı noktaları ve paketler\"\nSECTION_PRINTERS_AND_SPOOLS=\"Yazıcılar ve Biriktiriciler\"\nSECTION_PROGRAM_DETAILS=\"Program Ayrıntıları\"\nSECTION_SCHEDULED_TASKS=\"Zamanlanan görevler\"\nSECTION_SECURITY_FRAMEWORKS=\"Güvenlik çerçeveleri\"\nSECTION_SHELLS=\"Kabuklar\"\nSECTION_SNMP_SUPPORT=\"SNMP Desteği\"\nSECTION_SOFTWARE=\"Yazılım\"\nSECTION_SQUID_SUPPORT=\"Squid Desteği\"\nSECTION_SSH_SUPPORT=\"SSH Desteği\"\nSECTION_STORAGE=\"Depolama\"\nSECTION_SYSTEM_INTEGRITY=\"Yazılım: Sistem bütünlüğü\"\nSECTION_SYSTEM_TOOLING=\"Yazılım: Sistem araçları\"\nSECTION_SYSTEM_TOOLS=\"Sistem araçları\"\nSECTION_TIME_AND_SYNCHRONIZATION=\"Zaman ve Eşzamanlama\"\nSECTION_USB_DEVICES=\"USB Aygıtları\"\nSECTION_USERS_GROUPS_AND_AUTHENTICATION=\"Kullanıcılar, Gruplar ve Kimlik Doğrulama\"\nSECTION_VIRTUALIZATION=\"Sanallaştırma\"\nSECTION_WEBSERVER=\"Yazılım: web sunucusu\"\nSTATUS_ACTIVE=\" ETKİN\"\nSTATUS_CHECK_NEEDED=\" DENETİM GEREKLI\"\nSTATUS_DEBUG=\"HATA AYIKLAMA\"\nSTATUS_DEFAULT=\"ÖNTANIMLI\"\nSTATUS_DIFFERENT=\"FARKLI\"\nSTATUS_DISABLED=\"DEVRE DIŞI BIRAKILDI\"\nSTATUS_DONE=\"TAMAMLANDI\"\nSTATUS_ENABLED=\"ETKİNLEŞTİRİLDİ\"\nSTATUS_ERROR=\"HATA\"\nSTATUS_EXPOSED=\"AÇIKTA BIRAKILDI\"\nSTATUS_FAILED=\"BAŞARISIZ\"\nSTATUS_FILES_FOUND=\"DOSYALAR BULUNDU\"\nSTATUS_FOUND=\"BULUNDU\"\nSTATUS_HARDENED=\"SIKILAŞTIRILDI\"\nSTATUS_INSTALLED=\"KURULU\"\nSTATUS_LOCAL_ONLY=\"YALNIZCA YEREL\"\nSTATUS_MEDIUM=\"ORTA\"\nSTATUS_NO=\"HAYIR\"\nSTATUS_NO_UPDATE=\"GÜNCELLEME YOK\"\nSTATUS_NON_DEFAULT=\"ÖNTANIMLI OLMAYAN\"\nSTATUS_NONE=\"YOK\"\nSTATUS_NOT_ACTIVE=\"ETKİN DEĞİL\"\nSTATUS_NOT_CONFIGURED=\"YAPILANDIRILMADI\"\nSTATUS_NOT_DISABLED=\"DEVRE DIŞI BIRAKILMADI\"\nSTATUS_NOT_ENABLED=\"ETKİNLEŞTİRİLMEDİ\"\nSTATUS_NOT_FOUND=\"BULUNAMADI\"\nSTATUS_NOT_RUNNING=\"ÇALIŞMIYOR\"\nSTATUS_OFF=\"KAPALI\"\nSTATUS_OK=\"TAMAM\"\nSTATUS_ON=\"AÇIK\"\nSTATUS_PARTIALLY_HARDENED=\"KISMEN SIKILAŞTIRILDI\"\nSTATUS_PROTECTED=\"KORUMALI\"\nSTATUS_RUNNING=\"ÇALIŞIYOR\"\nSTATUS_SKIPPED=\"ATLANDI\"\nSTATUS_SUGGESTION=\"ÖNERİ\"\nSTATUS_UNKNOWN=\"BİLİNMİYOR\"\nSTATUS_UNSAFE=\"GÜVENLİ DEĞİL\"\nSTATUS_UPDATE_AVAILABLE=\"GÜNCELLEME VAR\"\nSTATUS_WARNING=\"UYARI\"\nSTATUS_WEAK=\"ZAYIF\"\nSTATUS_YES=\"EVET\"\nTEXT_UPDATE_AVAILABLE=\"güncelleme var\"\nTEXT_YOU_CAN_HELP_LOGFILE=\"Günlük dosyanızı göndererek yardımcı olabilirsiniz\"\n#SECTION_KERBEROS=\"Kerberos\"\n"
  },
  {
    "path": "default.prf",
    "content": "#################################################################################\n#\n#\n# Lynis - Default scan profile\n#\n#\n#################################################################################\n#\n#\n# This profile provides Lynis with most of its initial values to perform a\n# system audit.\n#\n#\n# WARNINGS\n# ----------\n#\n# Do NOT make changes to this file. Instead, copy only your changes into\n# the file custom.prf and put it in the same directory as default.prf\n#\n# To discover where your profiles are located: lynis show profiles\n#\n#\n# Lynis performs a strict check on profiles to avoid the inclusion of\n# possibly harmful injections. See include/profiles for details.\n#\n#\n#################################################################################\n#\n# All empty lines or with the # prefix will be skipped\n#\n#################################################################################\n\n# Use colored output\ncolors=yes\n\n# Compressed uploads (set to zero when errors with uploading occur)\ncompressed-uploads=yes\n\n# Amount of connections in WAIT state before reporting it as a suggestion\n#connections-max-wait-state=5000\n\n# Debug mode (for debugging purposes, extra data logged to screen)\n#debug=yes\n\n# Show non-zero exit code when warnings are found\nerror-on-warnings=no\n\n# Use Lynis in your own language (by default auto-detected)\nlanguage=\n\n# Log tests from another guest operating system (default: yes)\n#log-tests-incorrect-os=yes\n\n# Define if available NTP daemon is configured as a server or client on the network\n# values: server or client (default: client)\n#ntpd-role=client\n\n# Defines the role of the system (personal, workstation or server)\nmachine-role=server\n\n# Ignore some stratum 16 hosts (for example when running as time source itself)\n#ntp-ignore-stratum-16-peer=127.0.0.1\n\n# Profile name, will be used as title/description\nprofile-name=Default Audit Template\n\n# Number of seconds to pause between every test (0 is no pause)\npause-between-tests=0\n\n# Quick mode (do not wait for keypresses)\nquick=yes\n\n# Refresh software repositories to help detecting vulnerable packages\nrefresh-repositories=yes\n\n# Show solution for findings\nshow-report-solution=yes\n\n# Show inline tips about the tool\nshow-tool-tips=yes\n\n# Skip plugins\nskip-plugins=no\n\n# Skip a test (one per line)\n#skip-test=SSH-7408\n\n# Skip a particular option within a test (when applicable)\n#skip-test=SSH-7408:loglevel\n#skip-test=SSH-7408:permitrootlogin\n\n# Skip Lynis upgrade availability test (default: no)\n#skip-upgrade-test=yes\n\n# Locations where to search for SSL certificates (separate paths with a colon)\nssl-certificate-paths=/etc/apache2:/etc/dovecot:/etc/httpd:/etc/letsencrypt:/etc/pki:/etc/postfix:/etc/refind.d/keys:/etc/ssl:/opt/psa/var/certificates:/usr/local/psa/var/certificates:/usr/local/share/ca-certificates:/usr/share/ca-certificates:/usr/share/gnupg:/var/www:/srv/www\nssl-certificate-paths-to-ignore=/etc/letsencrypt/archive:\nssl-certificate-include-packages=no\n\n# Scan type - how deep the audit should be (light, normal or full)\ntest-scan-mode=full\n\n# Verbose output\nverbose=no\n\n\n#################################################################################\n#\n# Plugins\n# ---------------\n# Define which plugins are enabled\n#\n# Notes:\n# - Nothing happens if plugin isn't available\n# - There is no order in execution of plugins\n# - See documentation about how to use plugins and phases\n# - Some are for Lynis Enterprise users only\n#\n#################################################################################\n\n# Lynis plugins to enable\nplugin=authentication\nplugin=compliance\nplugin=configuration\nplugin=control-panels\nplugin=crypto\nplugin=dns\nplugin=docker\nplugin=file-integrity\nplugin=file-systems\nplugin=firewalls\nplugin=forensics\nplugin=hardware\nplugin=intrusion-detection\nplugin=intrusion-prevention\nplugin=kernel\nplugin=malware\nplugin=memory\nplugin=nginx\nplugin=pam\nplugin=processes\nplugin=security-modules\nplugin=software\nplugin=system-integrity\nplugin=systemd\nplugin=users\nplugin=krb5\n\n# Disable a particular plugin (will overrule an enabled plugin)\n#disable-plugin=authentication\n\n#################################################################################\n#\n# Kernel options\n# ---------------\n# config-data=, followed by:\n#\n# - Type                     = Set to 'sysctl'\n# - Setting                  = value of sysctl key (e.g. kernel.sysrq)\n# - Expected value           = Preferred value for key (e.g. 0)\n# - Hardening Points         = Number of hardening points (typically 1 point per key) (1)\n# - Description              = Textual description about the sysctl key(Disable magic SysRQ)\n# - Related file or command  = For example, sysctl -a to retrieve more details\n# - Solution field           = Specifies more details or where to find them (url:URL, text:TEXT, or -)\n#\n#################################################################################\n\n# Config\n# - Type (sysctl)\n# - Setting (kernel.sysrq)\n# - Expected value (0)\n# - Hardening Points (1)\n# - Description (Disable magic SysRQ)\n# - Related file or command (sysctl -a)\n# - Solution field (url:URL, text:TEXT, or -)\n\n# Processes\nconfig-data=sysctl;security.bsd.see_other_gids;0;1;Groups only see their own processes;sysctl -a;-;category:security;\nconfig-data=sysctl;security.bsd.see_other_uids;0;1;Users only see their own processes;sysctl -a;-;category:security;\nconfig-data=sysctl;security.bsd.stack_guard_page;1;1;Enable stack smashing protection (SSP)/ProPolice to defend against possible buffer overflows;-;category:security;\nconfig-data=sysctl;security.bsd.unprivileged_proc_debug;0;1;Unprivileged processes can not use process debugging;sysctl -a;-;category:security;\nconfig-data=sysctl;security.bsd.unprivileged_read_msgbuf;0;1;Unprivileged processes can not read the kernel message buffer;sysctl -a;-;category:security;\n\n# Kernel\nconfig-data=sysctl;fs.suid_dumpable;0;1;Restrict core dumps;sysctl -a;url:https;//www.kernel.org/doc/Documentation/sysctl/fs.txt;category:security;\nconfig-data=sysctl;fs.protected_fifos;2;1;Restrict FIFO special device creation behavior;sysctl -a;url:https;//www.kernel.org/doc/Documentation/sysctl/fs.txt;category:security;\nconfig-data=sysctl;fs.protected_hardlinks;1;1;Restrict hardlink creation behavior;sysctl -a;url:https;//www.kernel.org/doc/Documentation/sysctl/fs.txt;category:security;\nconfig-data=sysctl;fs.protected_regular;2;1;Restrict regular files creation behavior;sysctl -a;url:https;//www.kernel.org/doc/Documentation/sysctl/fs.txt;category:security;\nconfig-data=sysctl;fs.protected_symlinks;1;1;Restrict symlink following behavior;sysctl -a;url:https;//www.kernel.org/doc/Documentation/sysctl/fs.txt;category:security;\n#config-data=sysctl;kern.randompid=2345;Randomize PID numbers with a specific modulus;sysctl -a;-;category:security;\nconfig-data=sysctl;kern.sugid_coredump;0;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.core_setuid_ok;0;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.core_uses_pid;1;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.ctrl-alt-del;0;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.dmesg_restrict;1;1;Restrict use of dmesg;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.exec-shield-randomize;1;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.exec-shield;1;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.kptr_restrict;2;1;Restrict access to kernel symbols;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.maps_protect;1;1;Restrict access to /proc/[pid]/maps;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.modules_disabled;1;1;Restrict module loading once this sysctl value is loaded;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.perf_event_paranoid;2|3|4;1;Restrict unprivileged access to the perf_event_open() system call.;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.randomize_va_space;2;1;Randomize of memory address locations (ASLR);sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.suid_dumpable;0;1;Restrict core dumps;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.sysrq;0;1;Disable magic SysRQ;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.unprivileged_bpf_disabled;1;1;Restrict BPF for unprivileged users;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.use-nx;0;1;No description;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;kernel.yama.ptrace_scope;1|2|3;1;Disable process tracing for everyone;-;category:security;\n\n# Network\nconfig-data=sysctl;net.core.bpf_jit_harden;2;1;Hardened BPF JIT compilation;sysctl -a;url:https;//kernel.org/doc/Documentation/sysctl/kernel.txt;category:security;\nconfig-data=sysctl;net.inet.ip.linklocal.in.allowbadttl;0;\nconfig-data=sysctl;net.inet.tcp.always_keepalive;0;1;Disable TCP keep alive detection for dead peers as the keepalive can be spoofed;-;category:security;\n#config-data=sysctl;net.inet.tcp.fast_finwait2_recycle;1;1;Recycle FIN/WAIT states more quickly (DoS mitigation step, with risk of false RST);-;category:security;\nconfig-data=sysctl;net.inet.tcp.nolocaltimewait;1;1;Remove the TIME_WAIT state for loopback interface;-;category:security;\nconfig-data=sysctl;net.inet.tcp.path_mtu_discovery;0;1;Disable MTU discovery as many hosts drop the ICMP type 3 packets;-;category:security;\nconfig-data=sysctl;net.inet.icmp.bmcastecho;0;1;Ignore ICMP packets directed to broadcast address;-;category:security;\nconfig-data=sysctl;net.inet.tcp.icmp_may_rst;0;1;ICMP may not send RST to avoid spoofed ICMP/UDP floods;-;category:security;\nconfig-data=sysctl;net.inet.icmp.drop_redirect;1;1;Do not allow redirected ICMP packets;-;category:security;\nconfig-data=sysctl;net.inet.icmp.rediraccept;0;1;Disable incoming ICMP redirect routing redirects;-;category:security;\nconfig-data=sysctl;net.inet.icmp.timestamp;0;1;Disable timestamps;-;category:security;\nconfig-data=sysctl;net.inet.ip.accept_sourceroute;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.inet.ip.check_interface;1;1;Verify that a packet arrived on the right interface;-;category:security;\nconfig-data=sysctl;net.inet.ip.forwarding;0;1;Do not allow forwarding of traffic;-;category:security;\nconfig-data=sysctl;net.inet.ip.process_options;0;1;Ignore any IP options in the incoming packets;-;category:security;\nconfig-data=sysctl;net.inet.ip.random_id;1;1;Use a random IP id to each packet leaving the system;-;category:security;\nconfig-data=sysctl;net.inet.ip.redirect;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.inet.ip.sourceroute;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.inet.ip6.redirect;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.inet.tcp.blackhole;2;1;Do not sent RST but drop traffic when delivered to closed TCP port;-;category:security;\nconfig-data=sysctl;net.inet.tcp.drop_synfin;1;1;SYN/FIN packets will be dropped on initial connection;-;category:security;\nconfig-data=sysctl;net.inet.udp.blackhole;1;1;Do not sent RST but drop traffic when delivered to closed UDP port;-;category:security;\nconfig-data=sysctl;net.inet6.icmp6.rediraccept;0;1;Disable incoming ICMP redirect routing redirects;-;category:security;\nconfig-data=sysctl;net.inet6.ip6.forwarding;0;1;Do not allow forwarding of traffic;-;category:security;\nconfig-data=sysctl;net.inet6.ip6.fw.enable;1;1;Enable filtering;-;category:security;\nconfig-data=sysctl;net.inet6.ip6.redirect;0;1;Disable sending ICMP redirect routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.accept_redirects;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.accept_source_route;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.bootp_relay;0;1;Do not relay BOOTP packets;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.forwarding;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.log_martians;1;1;Log all packages for which the host does not have a path back to the source;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.mc_forwarding;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.proxy_arp;0;1;Do not relay ARP packets;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.rp_filter;1;1;Enforce ingress/egress filtering for packets;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.all.send_redirects;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.default.accept_redirects;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.default.accept_source_route;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.ipv4.conf.default.log_martians;1;1;Log all packages for which the host does not have a path back to the source;-;category:security;\nconfig-data=sysctl;net.ipv4.icmp_echo_ignore_broadcasts;1;1;Ignore ICMP packets directed to broadcast address;-;category:security;\nconfig-data=sysctl;net.ipv4.icmp_ignore_bogus_error_responses;1;1;Ignore-;category:security;\n#config-data=sysctl;net.ipv4.ip_forward;0;1;Do not forward traffic;-;category:security;\nconfig-data=sysctl;net.ipv4.tcp_syncookies;1;1;Use SYN cookies to prevent SYN attack;-;category:security;\nconfig-data=sysctl;net.ipv4.tcp_timestamps;0|1;1;Disable TCP time stamps or enable them with different offsets;-;category:security;\nconfig-data=sysctl;net.ipv6.conf.all.send_redirects;0;1;Disable/ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv6.conf.all.accept_redirects;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv6.conf.all.accept_source_route;0;1;Disable IP source routing;-;category:security;\nconfig-data=sysctl;net.ipv6.conf.default.accept_redirects;0;1;Disable/Ignore ICMP routing redirects;-;category:security;\nconfig-data=sysctl;net.ipv6.conf.default.accept_source_route;0;1;Disable IP source routing;-;category:security;\n\n# Other\nconfig-data=sysctl;dev.tty.ldisc_autoload;0;1;Disable loading of TTY line disciplines;-;category:security;\nconfig-data=sysctl;hw.kbd.keymap_restrict_change;4;1;Disable changing the keymap by non-privileged users;-;category:security;\n#sysctl;kern.securelevel;1^2^3;1;FreeBSD security level;\n#security.jail.jailed; 0\n#security.jail.jail_max_af_ips; 255\n#security.jail.mount_allowed; 0\n#security.jail.chflags_allowed; 0\n#security.jail.allow_raw_sockets; 0\n#security.jail.enforce_statfs; 2\n#security.jail.sysvipc_allowed; 0\n#security.jail.socket_unixiproute_only; 1\n#security.jail.set_hostname_allowed; 1\n#security.bsd.suser_enabled; 1\n#security.bsd.unprivileged_proc_debug; 1\n#security.bsd.conservative_signals; 1\n#security.bsd.unprivileged_read_msgbuf; 1\n#security.bsd.unprivileged_get_quota; 0\nconfig-data=sysctl;security.bsd.hardlink_check_gid;1;1;Unprivileged processes are not allowed to create hard links to files which are owned by other groups;-;category:security;\nconfig-data=sysctl;security.bsd.hardlink_check_uid;1;1;Unprivileged processes are not allowed to create hard links to files which are owned by other users;-;category:security;\n\n\n#################################################################################\n#\n# permfile\n# ---------------\n# permfile=file name:file permissions:owner:group:action:\n# Action = NOTICE or WARN\n# Examples:\n# permfile=/etc/test1.dat:600:root:wheel:NOTICE:\n# permfile=/etc/test1.dat:640:root:-:WARN:\n#\n#################################################################################\n\n#permfile=/etc/inetd.conf:rw-------:root:-:WARN:\n#permfile=/etc/fstab:rw-r--r--:root:-:WARN:\npermfile=/boot/grub/grub.cfg:rw-------:root:root:WARN:\npermfile=/boot/grub2/grub.cfg:rw-------:root:root:WARN:\npermfile=/boot/grub2/user.cfg:rw-------:root:root:WARN:\npermfile=/etc/at.allow:rw-------:root:-:WARN:\npermfile=/etc/at.deny:rw-------:root:-:WARN:\npermfile=/etc/cron.allow:rw-------:root:-:WARN:\npermfile=/etc/cron.deny:rw-------:root:-:WARN:\npermfile=/etc/crontab:rw-------:root:-:WARN:\npermfile=/etc/group:rw-r--r--:root:-:WARN:\npermfile=/etc/group-:rw-r--r--:root:-:WARN:\npermfile=/etc/hosts.allow:rw-r--r--:root:root:WARN:\npermfile=/etc/hosts.deny:rw-r--r--:root:root:WARN:\npermfile=/etc/issue:rw-r--r--:root:root:WARN:\npermfile=/etc/issue.net:rw-r--r--:root:root:WARN:\npermfile=/etc/lilo.conf:rw-------:root:-:WARN:\npermfile=/etc/motd:rw-r--r--:root:root:WARN:\npermfile=/etc/passwd:rw-r--r--:root:-:WARN:\npermfile=/etc/passwd-:rw-r--r--:root:-:WARN:\npermfile=/etc/ssh/sshd_config:rw-------:root:-:WARN:\npermfile=/etc/hosts.equiv:rw-r--r--:root:root:WARN:\npermfile=/etc/shosts.equiv:rw-r--r--:root:root:WARN:\npermfile=/root/.rhosts:rw-------:root:root:WARN:\npermfile=/root/.rlogin:rw-------:root:root:WARN:\npermfile=/root/.shosts:rw-------:root:root:WARN:\n\n# These permissions differ by OS\n#permfile=/etc/gshadow:---------:root:-:WARN:\n#permfile=/etc/gshadow-:---------:root:-:WARN:\n#permfile=/etc/shadow:---------:root:-:WARN:\n#permfile=/etc/shadow-:---------:root:-:WARN:\n\n\n#################################################################################\n#\n# permdir\n# ---------------\n# permdir=directory name:file permissions:owner:group:action when permissions are different:\n#\n#################################################################################\n\npermdir=/root/.ssh:rwx------:root:-:WARN:\npermdir=/etc/cron.d:rwx------:root:root:WARN:\npermdir=/etc/cron.daily:rwx------:root:root:WARN:\npermdir=/etc/cron.hourly:rwx------:root:root:WARN:\npermdir=/etc/cron.weekly:rwx------:root:root:WARN:\npermdir=/etc/cron.monthly:rwx------:root:root:WARN:\n\n\n# Ignore some specific home directories\n# One directory per line; directories will be skipped for home directory specific\n# checks, like file permissions, SSH and other configuration files\n#ignore-home-dir=/home/user\n\n\n# Allow promiscuous interfaces\n#   <option>:<promiscuous interface name>:<description>:\n#if_promisc:pflog0:pf log daemon interface:\n\n\n# The URL prefix and append to the URL for controls or your custom tests\n# Link will be formed as {control-url-protocol}://{control-url-prepend}CONTROL-ID{control-url-append}\n#control-url-protocol=https\n#control-url-prepend=cisofy.com/control/\n#control-url-append=/\n\n# The URL prefix and append to URL's for your custom tests\n#custom-url-protocol=https\n#custom-url-prepend=your-domain.example.org/control-info/\n#custom-url-append=/\n\n\n#################################################################################\n#\n# Operating system specific\n# -------------------------\n#\n#################################################################################\n\n# Skip the FreeBSD portaudit test\n#freebsd-skip-portaudit=yes\n\n# Skip security repository check for Debian based systems\n#debian-skip-security-repository=yes\n\n\n\n#################################################################################\n#\n# Lynis Enterprise options\n# ------------------------\n#\n#################################################################################\n\n# Allow this system to be purged when it is outdated (default: not defined).\n# This is useful for ephemeral systems which are short-lived.\n#allow-auto-purge=yes\n\n# Sometimes it might be useful to override the host identifiers.\n# Use only hexadecimal values (0-9, a-f), with 40 and 64 characters in length.\n#\n#hostid=40-char-hash\n#hostid2=64-char-hash\n\n# Lynis Enterprise license key\nlicense-key=\n\n# Proxy settings\n# Protocol (http, https, socks5)\n#proxy-protocol=https\n\n# Proxy server\n#proxy-server=10.0.1.250\n\n# Define proxy port to use\n#proxy-port=3128\n\n# Define the group names to link to this system (preferably single words). Default setting: append\n# To clear groups before assignment, add 'action:clear' as last groupname\n#system-groups=groupname1,groupname2,groupname3\n\n# Define which compliance standards are audited and reported on. Disable this if not required.\ncompliance-standards=cis,hipaa,iso27001,pci-dss\n\n# Provide the name of the customer/client\n#system-customer-name=mycustomer\n\n# Upload data to central server\nupload=no\n\n# The hostname/IP address to receive the data\nupload-server=\n\n# Provide options to cURL (or other upload tool) when uploading data.\n# upload-options=--insecure (use HTTPS, but skip certificate check for self-signed certificates)\nupload-options=\n\n# Link one or more tags to a system\n#tags=db,production,ssn-1304\n\n\n#EOF\n"
  },
  {
    "path": "developer.prf",
    "content": "# This profile is useful when creating your own tests, or debugging tests\n# lynis audit system --profile developer.prf\n\ndebug=yes\ndeveloper-mode=yes\nstrict=yes\nverbose=yes\n"
  },
  {
    "path": "extras/README",
    "content": "\n================================================================================\n\n    This directory contains tools for:\n    - Easy building customized packages\n    - Integrity checks and tools\n    - Development tools\n\n================================================================================\n"
  },
  {
    "path": "extras/bash_completion.d/lynis",
    "content": "# bash completion for lynis\n\n# version 1.0.1 (2019-07-13)\n# Michael Boelen <michael.boelen@cisofy.com>\n\n# lynis(8) completion\n_lynis()\n{\n    local cur prev\n    # opts nodig nosig\n\n    COMPREPLY=()\n    _get_comp_words_by_ref cur prev words\n\n    if [ $COMP_CWORD -eq 1 ]; then\n        # first parameter on line\n        case $cur in\n            -*)\n                COMPREPLY=( $( compgen -W '--help --info --version' -- \"$cur\" ) )\n                ;;\n            *)\n                COMPREPLY=( $( compgen -W 'audit generate show' -- \"$cur\" ) )\n                ;;\n        esac\n        return 0\n    elif [ $COMP_CWORD -eq 4 ]; then\n        # Stop after some specifics\n        if [ \"${COMP_WORDS[1]}\" = \"show\" -a \"${COMP_WORDS[2]}\" = \"details\" ]; then\n            return 0\n        fi\n    fi\n\n    # Check previous argument to share the available options\n    case $prev in\n        audit)\n            COMPREPLY=( $( compgen -W 'dockerfile system ' -- \"$cur\" ) )\n            ;;\n\n        show)\n            COMPREPLY=( $( compgen -W 'categories changelog commands dbdir details environment eol groups help hostids includedir language license logfile man options os pidfile plugindir profiles release releasedate report settings tests  version workdir ' -- \"$cur\" ) )\n            ;;\n\n        # Related items to show (lynis show XYZ)\n        categories)\n            return 0\n            ;;\n        changelog)\n            return 0\n            ;;\n        commands)\n            return 0\n            ;;\n        dbdir)\n            return 0\n            ;;\n        details)\n            local dbfile=\"\"\n            local dirs=\"/data/development/lynis /usr/local/lynis /usr/share/lynis\"\n            for d in ${dirs}; do\n                if [ -f \"${d}/db/tests.db\" ]; then\n                    local dbfile=\"/data/development/lynis/db/tests.db\"\n                fi\n            done\n            if [ -f \"${dbfile}\" ]; then\n                local suggestions=($(compgen -W \"$(awk -F: '$1 ~ /^[A-Z]/ {print $1}' ${dbfile})\" -- \"${cur}\"))\n                COMPREPLY=(\"${suggestions[@]}\")\n            else\n                COMPREPLY=($(compgen -W \"TEST-1234\" -- \"$cur\"))\n            fi\n            ;;\n        environment)\n            return 0\n            ;;\n        eol)\n            return 0\n            ;;\n        groups)\n            return 0\n            ;;\n        help)\n            return 0\n            ;;\n        hostids)\n            if [ \"${COMP_WORDS[1]}\" = \"generate\" -a \"${COMP_WORDS[2]}\" = \"hostids\" ]; then\n                COMPREPLY=($(compgen -W \"save\" -- \"$cur\"))\n            else\n                return 0\n            fi\n            ;;\n        includedir)\n            return 0\n            ;;\n        language)\n            return 0\n            ;;\n        license)\n            return 0\n            ;;\n        logfile)\n            return 0\n            ;;\n        man)\n            return 0\n            ;;\n        options)\n            return 0\n            ;;\n        os)\n            return 0\n            ;;\n        pidfile)\n            return 0\n            ;;\n        plugindir)\n            return 0\n            ;;\n        profiles)\n            return 0\n            ;;\n        release)\n            return 0\n            ;;\n        releasedate)\n            return 0\n            ;;\n        report)\n            return 0\n            ;;\n        settings)\n            return 0\n            ;;\n        tests)\n            return 0\n            ;;\n        version)\n            return 0\n            ;;\n        workdir)\n            return 0\n            ;;\n\n        generate)\n            COMPREPLY=( $( compgen -W 'hostids ' -- \"$cur\" ) )\n            ;;\n\n        # Options\n        --auditor)\n            COMPREPLY=( '\"Mr. Auditor\"' )\n            #return 0\n            ;;\n        --check-update|--help|--info|--version)\n            # all other options are noop with this command\n            return 0\n            ;;\n        --logfile)\n            COMPREPLY=( 'myfile.log' )\n            return 0\n            ;;\n        --plugin-dir)\n            _filedir -d\n            return 0\n            ;;\n        --profile)\n            COMPREPLY=( 'default.prf' )\n            return 0\n            ;;\n        --tests)\n            COMPREPLY=( '\"TEST-0001 TEST-0002 TEST-0003\"' )\n            return 0\n            ;;\n        --tests-from-category)\n            COMPREPLY=( '\"performance privacy security\"' )\n            return 0\n            ;;\n        --tests-from-groups)\n            COMPREPLY=( '\"accounting authentication\"' )\n            return 0\n            ;;\n        *)\n            COMPREPLY=( $( compgen -W ' \\\n                --auditor --cronjob --debug --quick --quiet --logfile --no-colors --no-log --pentest --reverse-colors \\\n                --tests --tests-from-category --tests-from-group --upload --verbose --slow-warning' -- \"$cur\" ) )\n            ;;\n    esac\n\n    return 0\n}\n\ncomplete -F _lynis lynis\n\n# Local variables:\n# mode: shell-script\n# sh-basic-offset: 4\n# sh-indent-comment: t\n# indent-tabs-mode: nil\n# End:\n# ex: ts=4 sw=4 et filetype=sh\n"
  },
  {
    "path": "extras/build-lynis.sh",
    "content": "#!/bin/sh\n\n#########################################################################\n#\n# Builds Lynis distribution\n#\n# Usage: this script creates Lynis builds\n#\n# *** NOTE ***\n# This script is not fully functional yet, several options like digital\n# signing, RPM/DEB package creation are missing.\n#\n#########################################################################\n#\n# Options:\n\n    echo \"[*] Activity [V] Successful [X] Error [=] Result\"\n    echo \"\"\n\n    # Umask used when creating files/directories\n    OPTION_UMASK=\"027\"\n\n    # Directory name used to create package related directories (like /usr/local/include/lynis)\n    OPTION_PACKAGE_DIRNAME=\"lynis\"\n\n    # Binary to test\n    OPTION_BINARY_FILE=\"../lynis\"\n\n    # Check number of parameters\n    if [ $# -eq 0 ]; then\n        echo \"[X] This build tool needs at least a version number (--version). Use --help for all parameters.\"\n        exit 1\n    fi\n\n    # Check parameters\n    case $1 in\n        --help)\n            echo \"Define version:\"\n            echo \"--version 1.2.3\"\n            exit 1\n        ;;\n        --version)\n            shift\n            LYNIS_VERSION=$1\n        ;;\n        *)\n            echo \"[X] Incorrect parameter\"\n            exit 1\n        ;;\n    esac\n\n#\n#########################################################################\n#\n# Functions:\n\n    # Clean temporary files up\n    CleanUp() {\n        if [ ! \"${TMPDIR}\" = \"\" -a -d \"${TMPDIR}\" ]; then\n            rm -rf ${TMPDIR}\n        fi\n    }\n\n    Exit() {\n        CleanUp\n        exit 0\n    }\n    ExitFatal() {\n        CleanUp\n        exit 1\n    }\n#\n#########################################################################\n#\n\n    # Clean files up if we get interrupted\n    trap CleanUp INT\n\n#\n#########################################################################\n#\n    MYUSER=$(whoami)\n    if [ \"${MYUSER}\" = \"\" ]; then\n        echo \"[X] Could not determine user\"\n    fi\n    if [ \"${MYUSER}\" = \"root\" ]; then\n        echo \"[X] This script should not be executed as root\"\n    fi\n\n\n    MYWORKDIR=$(pwd | awk -F / '{ for (i=1;i<=NF-2;i++){ printf $i\"/\" }; printf \"\\n\"}' | sed 's./$..')\n    if [ ! -d ${MYWORKDIR} ]; then\n        echo \"[X] Could not determine workdir (result: ${MYWORKDIR} seems invalid)\"\n        ExitFatal\n    else\n        echo \"[=] workdir: ${MYWORKDIR}\"\n    fi\n\n\n    MYBUILDDIR=\"/home/${MYUSER}/lynis-build\"\n    if [ ! -d ${MYBUILDDIR} ]; then\n        echo \"[X] ${MYBUILDDIR} not found\"\n        echo \"    Hint: create it with mkdir ${MYBUILDDIR}\"\n        ExitFatal\n    else\n        echo \"[=] builddir: ${MYBUILDDIR}\"\n    fi\n\n    NEEDED_DIRS=\"debbuild rpmbuild rpmbuild/BUILD rpmbuild/BUILDROOT rpmbuild/RPMS rpmbuild/SOURCES rpmbuild/SRPMS\"\n    for I in ${NEEDED_DIRS}; do\n        if [ ! -d \"${MYBUILDDIR}/${I}\" ]; then\n            echo \"[X] Missing directory: ${MYBUILDDIR}/${I}\"\n            echo \"   Hint: create subdirs with cd ${MYBUILDDIR} && mkdir -p ${NEEDED_DIRS}\"\n            ExitFatal\n        fi\n    done\n\n    DEBWORKDIR=\"${MYBUILDDIR}/debbuild\"\n    RPMWORKDIR=\"${MYBUILDDIR}/rpmbuild\"\n    echo \"[=] RPM workdir: ${RPMWORKDIR}\"\n    #echo \"Use: cd ${MYBUILDDIR} && mkdir rpm\"\n\n\n    # Check binaries\n\n    GITBUILDPACKAGEBINARY=$(which git-buildpackage)\n    if [ ! \"${GITBUILDPACKAGEBINARY}\" = \"\" ]; then\n        echo \"[=] git-buildpackage = ${GITBUILDPACKAGEBINARY}\"\n    else\n        echo \"[X] Can not find git-buildpackage binary\"\n        echo \"    Hint: install git-buildpackage\"\n        ExitFatal\n    fi\n\n    RPMBUILDBINARY=$(which rpmbuild)\n    if [ ! \"${RPMBUILDBINARY}\" = \"\" ]; then\n        echo \"[=] rpmbuild = ${RPMBUILDBINARY}\"\n    else\n        echo \"[X] Can not find rpmbuild binary\"\n        echo \"    Hint: install rpmbuild\"\n        ExitFatal\n    fi\n\n\n    # Set umask\n    umask ${OPTION_UMASK}\n    if [ $? -eq 0 ]; then\n        echo \"[V] Setting umask to ${OPTION_UMASK}\"\n    else\n        echo \"[X] Could not set umask\"\n        ExitFatal\n    fi\n\n    # Check if we are in dev directory\n    if [ -f ../lynis -a -f ./build-lynis.sh ]; then\n        echo \"[V] Active in proper directory\"\n    else\n        echo \"[X] This script should be executed from dev directory itself\"\n        ExitFatal\n    fi\n\n\n\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    # Create temporary build directory\n    TMPDIR=$(mktemp -d /tmp/lynis-BUILDROOT.XXXXXX)\n    if [ $? -eq 0 ]; then\n        echo \"[V] Creating temporary build directory\"\n        #echo \"    BUILDROOT: ${TMPDIR}\"\n    else\n        echo \"[X] Could not create temporary build directory\"\n        ExitFatal\n    fi\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    echo \"[*] Starting with building tarball\"\n\n    TARBALL=\"${MYBUILDDIR}/lynis_${LYNIS_VERSION}.orig.tar.gz\"\n    #if [ -f ${TARBALL} ]; then\n    #     echo \"[X] Tarball already exists \"\n    #     echo \"    Hint: remove ${TARBALL}\"\n    #     ExitFatal\n    #fi\n\n    # Create tarball\n\n    if [ -f ${TARBALL} ]; then\n        echo \"Tarball already exists for this version, not overwriting it\"\n    else\n        tar -C ${MYWORKDIR} --exclude=debian --exclude=README.md --exclude=.bzr* --exclude=.git* -c -z -f ${TARBALL} lynis 2> /dev/null\n        if [ -f ${TARBALL} ]; then\n            echo \"[V] Tarball created\"\n        else\n            echo \"[X] Tarball ${TARBALL} could not be created\"\n            ExitFatal\n        fi\n    fi\n\n    TARBALL_MD5=$(md5sum ${TARBALL})\n    TARBALL_SHA1=$(sha1sum ${TARBALL})\n\n    echo \"[*] Starting with RPM building process\"\n\n    # RPM creation\n    SOURCEFILE_RPM=\"${RPMWORKDIR}/SOURCES/lynis-${LYNIS_VERSION}.tar.gz\"\n    if [ -f ${SOURCEFILE_RPM} ]; then\n        if [ -f lynis.spec ]; then\n            # adjust version in spec file\n            VERSION_IN_SPECFILE=$(awk '/^Version:/ { print $2 }' lynis.spec)\n            echo \"[=] Found version ${VERSION_IN_SPECFILE}\"\n            if [ ${VERSION_IN_SPECFILE} = \"\" -o ! \"${VERSION_IN_SPECFILE}\" = \"${LYNIS_VERSION}\" ]; then\n                echo \"[X] Version in specfile is outdated\"\n                ExitFatal\n            fi\n            echo \"[*] Start RPM building\"\n            #${RPMBUILDBINARY} --quiet -ba -bl lynis.spec 2> /dev/null\n        else\n            echo \"[X] lynis.spec not found\"\n            ExitFatal\n        fi\n\n        RPMFILE=\"${RPMWORKDIR}/RPMS/noarch/lynis-${LYNIS_VERSION}-1.noarch.rpm\"\n        if [ -f ${RPMFILE} ]; then\n            echo \"[V] Building RPM successful!\"\n        else\n            echo \"[X] Could not find RPM file, most likely failed\"\n            echo \"    Expected: ${RPMFILE}\"\n            ExitFatal\n        fi\n    else\n        echo \"[X] Could not find source file (${SOURCEFILE_RPM})\"\n        echo \"    Hint: cp <lynis.tar.gz> ${SOURCEFILE_RPM}\"\n        #ExitFatal\n    fi\n\n    echo \"[*] Starting with DEB building process\"\n\n        DEBCHANGELOGFULLVERSION=$(head -n 1 ../debian/changelog | awk '{ print $2 }' | sed 's/(//' | sed 's/)//')\n        DEBCHANGELOGVERSION=$(echo ${DEBCHANGELOGFULLVERSION} | awk -F- '{ print $1 }')\n        DEBCHANGELOGVERSIONREV=$(echo ${DEBCHANGELOGFULLVERSION} | awk -F- '{ print $2 }')\n        if [ \"${LYNIS_VERSION}\" = \"${DEBCHANGELOGVERSION}\" ]; then\n            echo \"[V] Debian/changelog up-to-date\"\n        else\n            echo \"[X] Debian/changelog outdated\"\n            ExitFatal\n        fi\n\n#    BZRSTATUS=$(${BZRBINARY} status . 2>&1 > /dev/null; echo $?)\n#    if [ \"${BZRSTATUS}\" = \"0\" ]; then\n#        echo \"[V] bzr has proper directory tree\"\n#        DEBCHANGELOGFULLVERSION=$(head -n 1 debian/changelog | awk '{ print $2 }' | sed 's/(//' | sed 's/)//')\n#        DEBCHANGELOGVERSION=$(echo ${DEBCHANGELOGFULLVERSION} | awk -F- '{ print $1 }')\n#        DEBCHANGELOGVERSIONREV=$(echo ${DEBCHANGELOGFULLVERSION} | awk -F- '{ print $2 }')\n#        echo \"[=] Version in Debian changelog: ${DEBCHANGELOGVERSION} (revision: ${DEBCHANGELOGVERSIONREV})\"\n#        if [ \"${LYNIS_VERSION}\" = \"${DEBCHANGELOGVERSION}\" ]; then\n#            echo \"[V] Debian/changelog up-to-date\"\n#        else\n#            echo \"[X] Debian/changelog outdated\"\n##            ExitFatal\n#        fi\n#        # execute command\n#        # bzr builddeb . --build-dir ${DEBWORKDIR}/build-area/ --result-dir ${DEBWORKDIR}\n#    elif [ \"${BZRSTATUS}\" = \"3\" ]; then\n#        echo \"[X] Tree is not initialized for BZR\"\n#        echo \"    Hint: run bzr init while being in lynis directory (or bzr init ..)\"\n#        ExitFatal\n#    else\n#        echo \"[X] Unknown error\"\n#        echo \"Output: ${BZRSTATUS}\"\n#    fi\n\n    if [ ! -d ${MYBUILDDIR}/git ]; then\n        mkdir ${MYBUILDDIR}/git\n    fi\n\n    if [ -d ${MYBUILDDIR}/git/Lynis ]; then\n        echo \"git clone already exists\"\n        rm -rf ${MYBUILDDIR}/git/Lynis\n        #git checkout tags/${LYNIS_VERSION}\n    fi\n\n    git clone https://github.com/CISOfy/Lynis.git ${MYBUILDDIR}/git/Lynis\n\n    if [ -d ${MYBUILDDIR}/git/Lynis/debian/ ]; then\n        echo \"Copying build files into new tree\"\n        cp -R ../debian/* ${MYBUILDDIR}/git/Lynis/debian/\n        cd ${MYBUILDDIR}/git/Lynis/debian/\n        git add .\n        git commit -m \"Building process for Lynis release version ${LYNIS_VERSION}\"\n    else\n        echo \"[X] Could not copy debian directory and commit changes\"\n    fi\n    #git tag -l ${MYBUILDDIR}/git/Lynis\n\n    cd ..\n    echo \"Executing: ${GITBUILDPACKAGEBINARY} --git-tarball-dir=${MYBUILDDIR} --git-export-dir=${DEBWORKDIR} --git-ignore-new\"\n    ${GITBUILDPACKAGEBINARY} -S --git-tarball-dir=${MYBUILDDIR} --git-export-dir=${DEBWORKDIR} --git-ignore-new\n    cd ${MYWORKDIR}\n\n    echo \"[V] Done\"\n    echo \"\"\n    echo \"---------------------------------------------\"\n    echo \"RPM file:              ${RPMFILE}\"\n    echo \"DEB file:              ${DEBWORKDIR}/lynis_${LYNIS_VERSION}_amd64.deb\"\n    echo \"Tarball:               ${TARBALL}\"\n    echo \"Tarball (SHA1):        ${TARBALL_SHA1}\"\n    echo \"\"\n    echo \"Actions:\"\n    echo \" - Upload Debian package with dput (-f) my-ppa <source.changes>\"\n\n\n\n#=====================================================================\n\n# Stop the script at this stage, rest is under development\nExit\n\n#=====================================================================\n\n\n\n\n\n\n\n\n\n\n\n\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    # Test script for errors\n    echo -n \"- Test Lynis script                                    \"\n\n    # Is file there?\n    if [ ! -f ${OPTION_BINARY_FILE} ]; then echo \"BAD (can't find ${OPTION_BINARY_FILE})\"; exit 1; fi\n\n    # Check script\n    FIND=$(sh -n ${OPTION_BINARY_FILE} ; echo $?)\n    if [ $FIND -eq 0 ]; then\n        echo \"OK\"\n    else\n        echo \"BAD\"\n    fi\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    # Create SHA1 hashes\n    echo -n \"- Create SHA1 hashes                                   \"\n    SHA1HASH_LYNIS=$(grep -v '^#' ${OPTION_BINARY_FILE} | sha1)\n    echo \"DONE\"\n    echo \"    Lynis (SHA1): ${SHA1HASH_LYNIS}\"\n\n    # Add hashes to script\n    echo -n \"- Injecting SHA1 hash into Lynis script                \"\n    echo \"-NOT DONE-\"\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    echo -n \"- Cleaning up OpenBSD package build... \"\n    if [ -f openbsd/+CONTENTS ]; then rm openbsd/+CONTENTS; fi\n    echo \"DONE\"\n    OPENBSD_CONTENTS=\"openbsd/+CONTENTS\"\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    echo -n \"- Creating MD5 hashes...\"\n    PACKAGE_LIST_FILES=$(grep \"^file:\" files.dat | cut -d ':' -f3)\n\n    for I in ${PACKAGE_LIST_FILES}; do\n\n      echo -n \"${I} \"\n      #FULLNAME=$(grep \":file:include:\" files.dat)\n      #echo \"${FULLNAME}\" >> ${OPENBSD_CONTENTS}\n      echo \"${I}\" >> ${OPENBSD_CONTENTS}\n      FILE=\"../${I}\"\n      MD5HASH=$(md5 -q ${FILE})\n      echo \"@md5 ${MD5HASH}\" >> ${OPENBSD_CONTENTS}\n      echo \"@size 0000\" >> ${OPENBSD_CONTENTS}\n    done\n    echo \"\"\n\n\n\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n    echo -n \"- Cleaning up... \"\n\n    # Exit cleanly\n    Exit\n\n    echo \"DONE\"\n\n#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n# The End!\n\n"
  },
  {
    "path": "extras/check-lynis.sh",
    "content": "#!/bin/sh\n\n# Check for double ID numbers\ngrep -r Register .. | awk '{ if($2==\"Register\") { print $4 } }' | sort | uniq -c | awk '{ if ($1!=1) { print $2 } }'\n"
  },
  {
    "path": "extras/lynis.spec",
    "content": "#################################################################################\n#\n# Lynis spec file\n# -----------------\n#\n# This is a dummy file now. If you like to install the latest version as a\n# package, have a look at https://packages.cisofy.com\n#\n# Manual builds\n# -------------\n#\n# If you like to build your own rpm, use the software development kit, or copy\n# manually the lynis.spec file.\n#\n# mkdir -p /home/myuser/lynis\n# cd /home/myuser/lynis\n# git clone https://github.com/CISOfy/lynis\n# git clone https://github.com/CISOfy/lynis-sdk/\n# cd lynis-sdk\n# ./lynis-sdk build rpm\n#\n#################################################################################\n"
  },
  {
    "path": "extras/openbsd/+CONTENTS",
    "content": "CHANGELOG\n@md5 7e0ad05581d32d6051a3e22ef297e81d\n@size 0000\nFAQ\n@md5 b1e44a42bad55941868a743b24d01d8b\n@size 0000\nINSTALL\n@md5 a1574195ee66d7cf8b9947de2cce6ab4\n@size 0000\nLICENSE\n@md5 d32239bcb673463ab874e80d47fae504\n@size 0000\nREADME\n@md5 d46ffad53300d044ba02a037a7255ee8\n@size 0000\nTODO\n@md5 3486e35f6c705d8ea1e34c4a66ec7046\n@size 0000\ndefault.prf\n@md5 63e7765073d12b3b177a3587e3a4d6e4\n@size 0000\nlynis\n@md5 aab4c29e3f3dbcbf71b320b476b91c94\n@size 0000\nlynis.8\n@md5 604d717b4671972f7d53350f6efd1f10\n@size 0000\ninclude/functions\n@md5 cc8fd64fc868251453e54305ebd71b58\n@size 0000\ninclude/osdetection\n@md5 92fa7e249e65271a450bbb523cd36ce9\n@size 0000\ninclude/consts\n@md5 a39c3101c95bde6556374e4d8d4992d7\n@size 0000\ninclude/parameters\n@md5 4d983d717a62276b4e7df8b04b423ca2\n@size 0000\ninclude/profiles\n@md5 1781be3989c4f42aeb77656a7885bedd\n@size 0000\ninclude/tests_ports_packages\n@md5 d1754a6365ff04acbfacbb0208e2bb57\n@size 0000\ninclude/tests_boot_services\n@md5 746100f95e83097ab3f52f2a0287980b\n@size 0000\ninclude/tests_filesystems\n@md5 b5257d89440fa06f170dfb9bd35cb5fe\n@size 0000\ninclude/tests_networking\n@md5 0b4d329f118a1845abce2af6b7b19b25\n@size 0000\ninclude/tests_memory_processes\n@md5 b0e1df62f87bfc08bea1c21f4762c0ff\n@size 0000\ninclude/tests_kernel\n@md5 2ca3f7ec1924854e1076bebbdc654928\n@size 0000\ninclude/tests_logging\n@md5 9993368b9616248195ef350b470a7768\n@size 0000\ninclude/tests_authentication\n@md5 18b810aa4a87fde400b2da127edd2d04\n@size 0000\ninclude/tests_firewalls\n@md5 c12c6014b844595f866a76545c8c9893\n@size 0000\ninclude/tests_homedirs\n@md5 44760dd3a0ca3a8c665356b2c2028fc9\n@size 0000\ninclude/tests_shells\n@md5 489667c1fb7c12c3fa3dcef19ce45ebb\n@size 0000\ninclude/tests_printers_spools\n@md5 3c151550ff48df8e913b0b74a4fd1f2b\n@size 0000\ninclude/tests_file_integrity\n@md5 794ad1c924b23d0a808035961f47023c\n@size 0000\ninclude/tests_accounting\n@md5 1808a389d1b5ba8c6e708978839eb3d1\n@size 0000\ninclude/tests_banners\n@md5 6449b7069a4a08b83daa685e100b316e\n@size 0000\ninclude/tests_mail_messaging\n@md5 8424dab66b29ea5270bccbfc9dbd4cb2\n@size 0000\n"
  },
  {
    "path": "extras/systemd/lynis.service",
    "content": "#################################################################################\n#\n# Lynis service file for systemd\n#\n#################################################################################\n#\n# - Adjust path to link to location where Lynis binary is installed\n#\n# - Place this file together with the lynis.timer file in the related\n#   systemd directory (e.g. /etc/systemd/system/)\n#\n# - See details in lynis.timer file\n#\n#################################################################################\n\n[Unit]\nDescription=Security audit and vulnerability scanner\nDocumentation=https://cisofy.com/docs/\n\n[Service]\nNice=19\nIOSchedulingClass=best-effort\nIOSchedulingPriority=7\nType=simple\nExecStart=/path/to/lynis audit system --cronjob\n\n[Install]\nWantedBy=multi-user.target\n\n#EOF\n"
  },
  {
    "path": "extras/systemd/lynis.timer",
    "content": "#################################################################################\n#\n# Lynis timer file for systemd\n#\n#################################################################################\n#\n# - Place this file together with the lynis.service file in the related\n#   systemd directory (e.g. /etc/systemd/system)\n#\n# - Tell systemd you made changes\n#   systemctl daemon-reload\n#\n# - Enable and start the timer (so no reboot is needed):\n#   systemctl enable --now lynis.timer\n#\n#################################################################################\n\n[Unit]\nDescription=Daily timer for the Lynis security audit and vulnerability scanner\n\n[Timer]\nOnCalendar=daily\nRandomizedDelaySec=1800\nPersistent=false\n\n[Install]\nWantedBy=timers.target\n\n#EOF\n"
  },
  {
    "path": "extras/travis-ci/before_script.sh",
    "content": "#!/bin/sh\n\ncd ..\ngit clone --depth 1 https://github.com/CISOfy/lynis-sdk\n\n#EOF\n"
  },
  {
    "path": "include/binaries",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# * Check which binaries and tools are installed\n# * With the results a customized scan can be performed for every single system.\n#\n#################################################################################\n#\n    COMPILER_INSTALLED=0\n    IDLE_SESSION_KILLER_INSTALLED=0\n    MALWARE_SCANNER_INSTALLED=0\n#\n#################################################################################\n#\n    if [ ${CHECK_BINARIES} -eq 1 ]; then\n        InsertSection \"${SECTION_SYSTEM_TOOLS}\"\n        Display --indent 2 --text \"- Scanning available tools...\"\n        LogText \"Start scanning for available audit binaries and tools...\"\n\n        # Test        : CORE-1000\n        # Description : Check all system binaries\n        # Notes       : Always perform test, dependency for many other tests\n        Register --test-no CORE-1000 --weight L --network NO --description \"Check all system binaries\"\n        BINARY_PATHS_FOUND=\"\"; COUNT=0\n        Display --indent 2 --text \"- Checking system binaries...\"\n        LogText \"Status: Starting binary scan...\"\n\n        # Notes:\n        # - If PATH is empty, we use the predefined list in include/consts\n        # - Common paths first, then followed by more specific paths. This helps on the slightly ancient UNIX derivatives.\n        # - Avoid sorting the path list, as this might result in incorrect order of finding binaries (e.g. awk binary)\n\n        # Test if our PATH variable provides a set of paths. If so, reverse the order. If we discover the same binary\n        # multiple times, the one first in PATH should be used.\n        if [ -n \"${PATH}\" ]; then\n            PATH_REVERSED=$(echo \"${PATH}\" | sed 's/ /!!space!!/g' | awk -F: '{ for (i=NF; i>1; i--) printf(\"%s \",$i); print $1; }')\n            BIN_PATHS=$(echo \"${PATH_REVERSED}\" | tr ':' ' ')\n        fi\n\n        # First test available locations that may be suspicious or dangerous\n        for SCANDIR in ${BIN_PATHS}; do\n            FOUND=0\n            if [ \"${SCANDIR}\" = \".\" ]; then FOUND=1; MSG=\"Found single dot (.) in PATH\"\n            elif [ \"${SCANDIR}\" = \"..\" ]; then FOUND=1; MSG=\"Found double dot (..) in PATH\"\n            elif echo \"${SCANDIR}\" | grep '^\\.\\.' > /dev/null; then FOUND=1; MSG=\"Found path starting with double dot (..) in PATH\"\n            elif echo \"${SCANDIR}\" | grep '^[a-zA-Z]' > /dev/null; then FOUND=1; MSG=\"Found relative path in PATH\"\n            fi\n            if [ ${FOUND} -eq 1 ]; then\n                # Stop execution if privileged, otherwise continue but warn user\n                if [ ${PRIVILEGED} -eq 1 ]; then\n                    ExitFatal \"Suspicious location (${SCANDIR}) in PATH discovered. Quitting...\"\n                else\n                    Display --indent 4 --text \"Warning: suspicious location (${SCANDIR}) in PATH\"\n                    ReportWarning \"${TEST_NO}\" \"Suspicious location in PATH discovered\" \"text:${MSG}\"\n                    sleep 1\n                fi\n            fi\n        done\n\n        NSUID_BINARIES=0\n        NSGID_BINARIES=0\n        SUID_BINARIES=\n        SGID_BINARIES=\n        # Now perform binary detection\n        for SCANDIR in ${BIN_PATHS}; do\n            SCANDIR=$(echo \"${SCANDIR}\" | sed 's/!!space!!/ /g')\n            LogText \"Test: Checking binaries in directory ${SCANDIR}\"\n            ORGPATH=\"\"\n            if [ -d \"${SCANDIR}\" ]; then\n                SKIPDIR=0\n                if [ -L \"${SCANDIR}\" ]; then\n                    LogText \"Result: directory exists, but is actually a symlink\"\n                    ShowSymlinkPath ${SCANDIR}\n                    if [ ${FOUNDPATH} -eq 1 ]; then\n                        if [ -n \"${SYMLINK}\" -a -d ${SYMLINK} ]; then\n                            # Set path to new location\n                            LogText \"Result: found the path behind this symlink (${SCANDIR} --> ${sFILE})\"\n                            ORGPATH=\"${SCANDIR}\"\n                            SCANDIR=\"${sFILE}\"\n                        else\n                            SKIPDIR=1; LogText \"Result: Symlink variable empty, or directory to symlink is non-existing\"\n                        fi\n                    else\n                        SKIPDIR=1; LogText \"Result: Could not find the location of this symlink, or is not a directory\"\n                    fi\n                fi\n\n                # Add a space to make sure we discover a related directory if it was already scanned\n                # The grep -v is to prevent a match /usr/bin in something like /usr/bin/core_perl\n                FIND=$(echo ${BINARY_PATHS_FOUND} | grep \", ${SCANDIR}\" | grep -v \", ${SCANDIR}/\")\n                if [ -n \"${FIND}\" ]; then\n                    SKIPDIR=1; LogText \"Result: Skipping this directory as it was already scanned\"\n                fi\n\n                if [ ${SKIPDIR} -eq 0 ]; then\n                    BINARY_PATHS_FOUND=\"${BINARY_PATHS_FOUND}, ${SCANDIR}\"\n                    LogText \"Directory ${SCANDIR} exists. Starting directory scanning...\"\n\n                    # Show the contents of the directory with binaries, ignore directories\n                    FIND=$(ls -p \"${SCANDIR}\" | grep -v '/$')\n                    for FILENAME in ${FIND}; do\n                        COUNT=$((COUNT + 1))\n                        BINARY=\"${SCANDIR}/${FILENAME}\"\n                        DISCOVERED_BINARIES=\"${DISCOVERED_BINARIES}${BINARY} \"\n                        if [ -u \"${BINARY}\" ]; then\n                            NSUID_BINARIES=$((NSUID_BINARIES + 1))\n                            SUID_BINARIES=\"${SUID_BINARIES}${BINARY} \"\n                        fi\n                        if [ -g \"${BINARY}\" ]; then\n                            NSGID_BINARIES=$((NSGID_BINARIES + 1))\n                            SGID_BINARIES=\"${SGID_BINARIES}${BINARY} \"\n                        fi\n                        # Optimized, much quicker (limited file access needed)\n                        case ${FILENAME} in\n                            aa-status)              AASTATUSBINARY=${BINARY};          LogText \"  Found known binary: aa-status (apparmor component) - ${BINARY}\" ;;\n                            afick.pl)               AFICKBINARY=${BINARY};             LogText \"  Found known binary: afick (file integrity checker) - ${BINARY}\" ;;\n                            aide)                   AIDEBINARY=${BINARY};              LogText \"  Found known binary: aide (file integrity checker) - ${BINARY}\" ;;\n                            apache2)                HTTPDBINARY=${BINARY};             LogText \"  Found known binary: apache2 (web server) - ${BINARY}\" ;;\n                            apt)                    APTBINARY=${BINARY};               LogText \"  Found known binary: apt (package manager) - ${BINARY}\" ;;\n                            apk)                    APKBINARY=${BINARY};               LogText \"  Found known binary: apk (package manager) - ${BINARY}\" ;;\n                            arch-audit)             ARCH_AUDIT_BINARY=\"${BINARY}\";     LogText \"  Found known binary: arch-audit (auditing utility to test for vulnerable packages) - ${BINARY}\" ;;\n                            auditd)                 AUDITDBINARY=${BINARY};            LogText \"  Found known binary: auditd (audit framework) - ${BINARY}\" ;;\n                            awk)                    AWKBINARY=${BINARY};               LogText \"  Found known binary: awk (string tool) - ${BINARY}\" ;;\n                            as)                     ASBINARY=\"${BINARY}\";              COMPILER_INSTALLED=1;                  LogText \"  Found known binary: as (compiler) - ${BINARY}\" ;;\n                            auditctl)               AUDITCTLBINARY=\"${BINARY}\";        LogText \"  Found known binary: auditctl (control utility for audit daemon) - ${BINARY}\" ;;\n                            autolog)                AUTOLOGBINARY=\"${BINARY}\";         IDLE_SESSION_KILLER_INSTALLED=1;       LogText \"  Found known binary: autolog (idle session killer) - ${BINARY}\" ;;\n                            base64)                 BASE64BINARY=\"${BINARY}\";          LogText \"  Found known binary: base64 (encoding tool) - ${BINARY}\" ;;\n                            blkid)                  BLKIDBINARY=\"${BINARY}\";           LogText \"  Found known binary: blkid (information about block devices) - ${BINARY}\" ;;\n                            bootctl)                BOOTCTLBINARY=\"${BINARY}\";         LogText \"  Found known binary: bootctl (systemd-boot manager utility) - ${BINARY}\" ;;\n                            bro)                    BROBINARY=\"${BINARY}\";             LogText \"  Found known binary: bro (IDS) - ${BINARY}\" ;;\n                            cat)                    CAT_BINARY=\"${BINARY}\";            LogText \"  Found known binary: cat (generic file handling) - ${BINARY}\" ;;\n                            cc)                     CCBINARY=\"${BINARY}\";              COMPILER_INSTALLED=1;  LogText \"  Found known binary: cc (compiler) - ${BINARY}\" ;;\n                            chkconfig)              CHKCONFIGBINARY=${BINARY};         LogText \"  Found known binary: chkconfig (administration tool) - ${BINARY}\" ;;\n                            clamconf)               CLAMCONF_BINARY=${BINARY};         LogText \"  Found known binary: clamconf (information about ClamAV) - ${BINARY}\" ;;\n                            clamscan)               CLAMSCANBINARY=${BINARY};          LogText \"  Found known binary: clamscan (AV scanner) - ${BINARY}\" ;;\n                            clang)                  CLANGBINARY=${BINARY};             COMPILER_INSTALLED=1;  LogText \"  Found known binary: clang (compiler) - ${BINARY}\" ;;\n                            cfagent)                CFAGENTBINARY=\"${BINARY}\";         FILE_INT_TOOL_FOUND=1;                 LogText \"  Found known binary: cfengine agent (configuration tool) - ${BINARY}\" ;;\n                            chkrootkit)             CHKROOTKITBINARY=\"${BINARY}\";      MALWARE_SCANNER_INSTALLED=1;           LogText \"  Found known binary: chkrootkit (malware scanner) - ${BINARY}\" ;;\n                            cmd_daemon)             CMDBINARY=${BINARY};               LogText \"  Found known binary: cmd (audit framework) - ${BINARY}\" ;;\n                            comm)                   COMMBINARY=\"${BINARY}\";            LogText \"  Found known binary: comm (file compare) - ${BINARY}\" ;;\n                            cryptsetup)             CRYPTSETUPBINARY=\"${BINARY}\";      LogText \"  Found known binary: cryptsetup (block device encryption) - ${BINARY}\" ;;\n                            csum)                   CSUMBINARY=\"${BINARY}\";            LogText \"  Found known binary: csum (hashing tool on AIX) - ${BINARY}\" ;;\n                            curl)                   CURLBINARY=\"${BINARY}\";            CURLVERSION=$(${BINARY} --version | grep \"^curl\" | awk '{ if ($1==\"curl\") { print $2 }}'); LogText \"  Found known binary: curl (browser, download utility) - ${BINARY}\" ;;\n                            cut)                    CUTBINARY=\"${BINARY}\";             LogText \"  Found known binary: cut (text stream editor) - ${BINARY}\" ;;\n                            debsecan)               DEBSECANBINARY=\"${BINARY}\";        LogText \"  Found known binary: debsecan (package vulnerability checking) - ${BINARY}\" ;;\n                            debsums)                DEBSUMSBINARY=\"${BINARY}\";         LogText \"  Found known binary: debsums (package integrity checking) - ${BINARY}\" ;;\n                            dig)                    DIGBINARY=${BINARY};               LogText \"  Found known binary: dig (network/dns tool) - ${BINARY}\" ;;\n                            dmidecode)              DMIDECODEBINARY=${BINARY};         LogText \"  Found known binary: dmidecode (hardware collector tool) - ${BINARY}\" ;;\n                            dnf)                    DNFBINARY=\"${BINARY}\";             LogText \"  Found known binary: dnf (package manager) - ${BINARY}\" ;;\n                            dnsdomainname)          DNSDOMAINNAMEBINARY=\"${BINARY}\";   LogText \"  Found known binary: dnsdomainname (DNS domain) - ${BINARY}\" ;;\n                            docker)                 DOCKERBINARY=\"${BINARY}\";          LogText \"  Found known binary: docker (container technology) - ${BINARY}\" ;;\n                            domainname)             DOMAINNAMEBINARY=\"${BINARY}\";      LogText \"  Found known binary: domainname (NIS domain) - ${BINARY}\" ;;\n                            dpkg)                   DPKGBINARY=\"${BINARY}\";            LogText \"  Found known binary: dpkg (package management) - ${BINARY}\" ;;\n                            xbps-query)             XBPSBINARY=\"${BINARY}\";            LogText \"  Found known binary: xbps (package management) - ${BINARY}\" ;;\n                            equery)                 EQUERYBINARY=\"${BINARY}\";          LogText \"  Found known binary: query (package manager) - ${BINARY}\" ;;\n                            evmctl)                 EVMCTLBINARY=${BINARY};            LogText \"  Found known binary: evmctl (IMA/EVM tool) - ${BINARY}\" ;;\n                            exim)                   EXIMBINARY=\"${BINARY}\";            EXIMVERSION=$(${BINARY} -bV | grep 'Exim version' | awk '{ print $3 }' | xargs); LogText \"  Found known binary ${BINARY} (version ${EXIMVERSION})\" ;;\n                            fail2ban-server)        FAIL2BANBINARY=\"${BINARY}\";        LogText \"  Found known binary: fail2ban (IPS tool) - ${BINARY}\" ;;\n                            file)                   FILEBINARY=\"${BINARY}\";            LogText \"  Found known binary: file (file type detection) - ${BINARY}\" ;;\n                            find)                   FINDBINARY=\"${BINARY}\";            LogText \"  Found known binary: find (search tool) - ${BINARY}\" ;;\n                            g++)                    GPLUSPLUSBINARY=\"${BINARY}\";       COMPILER_INSTALLED=1;  LogText \"  Found known binary: g++ (compiler) - ${BINARY}\" ;;\n                            gcc)                    GCCBINARY=\"${BINARY}\";             COMPILER_INSTALLED=1;  LogText \"  Found known binary: gcc (compiler) - ${BINARY}\" ;;\n                            getcap)                 GETCAPBINARY=\"${BINARY}\";          LogText \"  Found known binary: getcap (kernel capabilities) - ${BINARY}\" ;;\n                            getent)                 GETENT_BINARY=\"${BINARY}\";         LogText \"  Found known binary: getent (query tool for name service switch libraries) - ${BINARY}\" ;;\n                            gradm)                  GRADMBINARY=${BINARY};             LogText \"  Found known binary: gradm (Grsecurity Administration Utility) - ${BINARY}\" ;;\n                            grep)                   GREPBINARY=${BINARY};              LogText \"  Found known binary: grep (text search) - ${BINARY}\" ;;\n                            grpck)                  GRPCKBINARY=\"${BINARY}\";           LogText \"  Found known binary: grpck (consistency checker) - ${BINARY}\" ;;\n                            grub2-install)          GRUB2INSTALLBINARY=${BINARY};      LogText \"  Found known binary: grub2-install (installer for boot loader) - ${BINARY}\" ;;\n                            gzip)                   GZIPBINARY=\"${BINARY}\";            LogText \"  Found known binary: gzip (compressing utility) - ${BINARY}\" ;;\n                            head)                   HEADBINARY=\"${BINARY}\";            LogText \"  Found known binary: head (text filter) - ${BINARY}\" ;;\n                            httpd)                  HTTPDBINARY=\"${BINARY}\";           LogText \"  Found known binary: httpd (web server) - ${BINARY}\" ;;\n                            httpd2-prefork)         HTTPDBINARY=${BINARY};             LogText \"  Found known binary: apache2 (web server) - ${BINARY}\" ;;\n                            initctl)                INITCTLBINARY=${BINARY};           SERVICE_MANAGER=\"upstart\";  LogText \"  Found known binary: initctl (client to upstart init) - ${BINARY}\" ;;\n                            ifconfig)               IFCONFIGBINARY=\"${BINARY}\";        LogText \"  Found known binary: ipconfig (IP configuration) - ${BINARY}\" ;;\n                            integritysetup)         INTEGRITYSETUPBINARY=\"${BINARY}\";  LogText \"  Found known binary: integritysetup (dm-integrity setup tool) - ${BINARY}\" ;;\n                            ip)                     IPBINARY=\"${BINARY}\";              LogText \"  Found known binary: ip (IP configuration) - ${BINARY}\" ;;\n                            ipf)                    IPFBINARY=\"${BINARY}\";             LogText \"  Found known binary: ipf (firewall) - ${BINARY}\" ;;\n                            iptables)               IPTABLESBINARY=\"${BINARY}\";        LogText \"  Found known binary: iptables (firewall) - ${BINARY}\" ;;\n                            iptables-save)          IPTABLESSAVEBINARY=\"${BINARY}\";    LogText \"  Found known binary: iptables-save (firewall) - ${BINARY}\" ;;\n                            istat)                  ISTATBINARY=\"${BINARY}\";           LogText \"  Found known binary: istat (file information) - ${BINARY}\" ;;\n                            journalctl)             JOURNALCTLBINARY=\"${BINARY}\";      LogText \"  Found known binary: journalctl (systemd journal) - ${BINARY}\" ;;\n                            kadmin.local)           KADMINLOCALBINARY=\"${BINARY}\";     LogText \"  Found known binary: kadmin.local (krb5) - ${BINARY}\" ;;\n                            kdb5_util)              KDB5UTILBINARY=\"${BINARY}\";        LogText \"  Found known binary: kdb5_util (krb5) - ${BINARY}\" ;;\n                            kldstat)                KLDSTATBINARY=\"${BINARY}\";         LogText \"  Found known binary: kldstat (kernel modules) - ${BINARY}\" ;;\n                            kstat)                  KSTATBINARY=\"${BINARY}\";           LogText \"  Found known binary: kstat (kernel statistics) - ${BINARY}\" ;;\n                            launchctl)              LAUNCHCTL_BINARY=\"${BINARY}\";      SERVICE_MANAGER=\"launchd\"; LogText \"  Found known binary: launchctl (launchd client) - ${BINARY}\" ;;\n                            locate)                 LOCATEBINARY=\"${BINARY}\";          LogText \"  Found known binary: locate (file database) - ${BINARY}\" ;;\n                            logrotate)              LOGROTATEBINARY=\"${BINARY}\";       LogText \"  Found known binary: logrotate (log rotation tool) - ${BINARY}\" ;;\n                            ls)                     LSBINARY=\"${BINARY}\";              LogText \"  Found known binary: ls (file listing) - ${BINARY}\" ;;\n                            lsattr)                 LSATTRBINARY=\"${BINARY}\";          LogText \"  Found known binary: lsattr (file attributes) - ${BINARY}\" ;;\n                            lsblk)                  LSBLKBINARY=\"${BINARY}\";           LogText \"  Found known binary: lsblk (block devices) - ${BINARY}\" ;;\n                            lsmod)                  LSMODBINARY=\"${BINARY}\";           LogText \"  Found known binary: lsmod (kernel modules) - ${BINARY}\" ;;\n                            lsof)\n                                LSOFBINARY=\"${BINARY}\"\n                                LogText \"  Found known binary: lsof (open files) - ${BINARY}\"\n                                DATA=$(${LSOFBINARY} -h 2>&1 | grep \"\\-K \\[i\\] list\\|\\(i\\)gn tasKs\")\n                                if [ $? -eq 0 ]; then\n                                    LogText \"Note: added -K i to ignore tasks on Linux\"\n                                    LSOF_EXTRA_OPTIONS=\" -K i\"\n                                fi\n                            ;;\n                            lsvg)                   LSVGBINARY=${BINARY};              LogText \"  Found known binary: lsvg (volume manager) - ${BINARY}\" ;;\n                            lvdisplay)              LVDISPLAYBINARY=\"${BINARY}\";       LogText \"  Found known binary: lvdisplay (LVM tool) - ${BINARY}\" ;;\n                            lynx)                   LYNXBINARY=\"${BINARY}\";            LYNXVERSION=$(${BINARY} -version | grep \"^Lynx Version\" | cut -d ' ' -f3); LogText \"Found known binary: lynx (browser) - ${BINARY} (version ${LYNXVERSION})\" ;;\n                            maldet)                 LMDBINARY=\"${BINARY}\";             MALWARE_SCANNER_INSTALLED=1;           LogText \"  Found known binary: maldet (Linux Malware Detect, malware scanner) - ${BINARY}\" ;;\n                            md5)                    MD5BINARY=\"${BINARY}\";             LogText \"  Found known binary: md5 (hash tool) - ${BINARY}\" ;;\n                            md5sum)                 MD5BINARY=\"${BINARY}\";             LogText \"  Found known binary: md5sum (hash tool) - ${BINARY}\" ;;\n                            mdatp)                  MDATPBINARY=\"${BINARY}\";           MALWARE_SCANNER_INSTALLED=1;           LogText \"  Found known binary: mdatp (Microsoft Defender ATP, malware scanner) - ${BINARY}\" ;;\n                            modprobe)               MODPROBEBINARY=\"${BINARY}\";        LogText \"  Found known binary: modprobe (kernel modules) - ${BINARY}\" ;;\n                            mount)                  MOUNTBINARY=\"${BINARY}\";           LogText \"  Found known binary: mount (disk utility) - ${BINARY}\" ;;\n                            mtree)                  MTREEBINARY=\"${BINARY}\";           LogText \"  Found known binary: mtree (mapping directory tree) - ${BINARY}\" ;;\n                            mysql)                  MYSQLCLIENTBINARY=\"${BINARY}\";     MYSQLCLIENTVERSION=$(${BINARY} -V | awk '{ if ($4==\"Distrib\") { print $5 }}' | sed 's/,//g') ;  LogText \"Found ${BINARY} (version: ${MYSQLCLIENTVERSION})\" ;;\n                            named-checkconf)        NAMEDCHECKCONFBINARY=\"${BINARY}\";  LogText \"  Found known binary: named-checkconf (BIND configuration analyzer) - ${BINARY}\" ;;\n                            netstat)                NETSTATBINARY=\"${BINARY}\";         LogText \"  Found known binary: netstat (network statistics) - ${BINARY}\" ;;\n                            nft)                    NFTBINARY=\"${BINARY}\";             LogText \"  Found known binary: nft (nftables client) - ${BINARY}\" ;;\n                            nmap)                   NMAPBINARY=\"${BINARY}\";            NMAPVERSION=$(${BINARY} -V | grep \"^Nmap version\" | awk '{ print $3 }'); LogText \"Found ${BINARY} (version ${NMAPVERSION})\" ;;\n                            ntpctl)                 NTPCTLBINARY=\"${BINARY}\";                LogText \"  Found known binary: ntpctl (openntpd client) - ${BINARY}\" ;;\n                            ntpq)                   NTPQBINARY=\"${BINARY}\";            LogText \"  Found known binary ntpq (time daemon client) - ${BINARY}\" ;;\n                            osiris)                 OSIRISBINARY=\"${BINARY}\";          LogText \"  Found known binary: osiris - ${BINARY}\" ;;\n                            openssl)                OPENSSLBINARY=\"${BINARY}\";         OPENSSLVERSION=$(${BINARY} version 2> /dev/null | head -n 1 | awk '{ print $2 }' | xargs); LogText \"Found ${BINARY} (version ${OPENSSLVERSION})\" ;;\n                            pacman)\n                                if [ -z \"$(echo \"${BINARY}\" | grep -E \"/usr(/local)?/games\")\" ]; then\n                                    PACMANBINARY=\"${BINARY}\"\n                                    LogText \"  Found known binary: pacman (package manager) - ${BINARY}\"\n                                fi\n                            ;;\n                            perl)                   PERLBINARY=\"${BINARY}\";            PERLVERSION=$(${BINARY} -V:version | sed 's/^version=//' | sed 's/;//' | xargs); LogText \"Found ${BINARY} (version ${PERLVERSION})\" ;;\n                            pgrep)                  PGREPBINARY=\"${BINARY}\";           LogText \"  Found known binary: pgrep (search in process list) - ${BINARY}\" ;;\n                            php)                    PHPBINARY=\"${BINARY}\";             PHPVERSION=$(${BINARY} -v | awk '{ if ($1==\"PHP\") { print $2 }}' | head -1); LogText \"Found known binary: php (programming language interpreter) - ${BINARY} (version ${PHPVERSION})\" ;;\n                            pkg)                    PKG_BINARY=\"${BINARY}\";            LogText \"  Found known binary: pkg (software package administration) - ${BINARY}\" ;;\n                            pkg_admin)              PKGADMINBINARY=\"${BINARY}\";        LogText \"  Found known binary: pkg_admin (software package administration) - ${BINARY}\" ;;\n                            pkg_info)               PKGINFOBINARY=\"${BINARY}\";         LogText \"  Found known binary: pkg_info (software package information) - ${BINARY}\" ;;\n                            postconf)               POSTCONFBINARY=\"${BINARY}\";        LogText \"  Found known binary: postconf (postfix configuration) - ${BINARY}\" ;;\n                            postfix)                POSTFIXBINARY=\"${BINARY}\";         LogText \"  Found known binary: postfix (postfix binary) - ${BINARY}\" ;;\n                            prelink)                PRELINKBINARY=\"${BINARY}\";         LogText \"  Found known binary: prelink (system optimizer) - ${BINARY}\" ;;\n                            pfctl)                  PFCTLBINARY=\"${BINARY}\";           LogText \"  Found known binary: pfctl (client to pf firewall) - ${BINARY}\" ;;\n                            ps)                     PSBINARY=\"${BINARY}\";              LogText \"  Found known binary: ps (process listing) - ${BINARY}\" ;;\n                            puppet)                 PUPPETBINARY=\"${BINARY}\";          LogText \"  Found known binary: puppet (automation tooling) - ${BINARY}\" ;;\n                            puppetmasterd)          PUPPETMASTERDBINARY=\"${BINARY}\";   LogText \"  Found known binary: puppetmasterd (puppet master daemon) - ${BINARY}\" ;;\n                            python)                 PYTHONBINARY=\"${BINARY}\";          PYTHONVERSION=$(${BINARY}  --version 2>&1 | sed 's/^Python //'); LogText \"Found known binary: ${FILENAME} (programming language interpreter) - ${BINARY} (version ${PYTHONVERSION})\" ;;\n                            python2)                PYTHON2BINARY=\"${BINARY}\";         PYTHON2VERSION=$(${BINARY}  --version 2>&1 | sed 's/^Python //'); LogText \"Found known binary: ${FILENAME} (programming language interpreter) - ${BINARY} (version ${PYTHON2VERSION})\" ;;\n                            python3)                PYTHON3BINARY=\"${BINARY}\";         PYTHON3VERSION=$(${BINARY}  --version 2>&1 | sed 's/^Python //'); LogText \"Found known binary: ${FILENAME} (programming language interpreter) - ${BINARY} (version ${PYTHON3VERSION})\" ;;\n                            rcctl)                  RCCTLBINARY=\"${BINARY}\";           LogText \"  Found known binary: rcctl (services and daemons configuration and control) - ${BINARY}\" ;;\n                            readlink)               READLINKBINARY=\"${BINARY}\";        LogText \"  Found known binary: readlink (follows symlinks) - ${BINARY}\" ;;\n                            resolvectl)             RESOLVECTLBINARY=\"${BINARY}\";      LogText \"  Found known binary: resolvectl (systemd-resolved DNS resolver manager) - ${BINARY}\" ;;\n                            rkhunter)               RKHUNTERBINARY=\"${BINARY}\";        MALWARE_SCANNER_INSTALLED=1;           LogText \"  Found known binary: rkhunter (malware scanner) - ${BINARY}\" ;;\n                            rootsh)                 ROOTSHBINARY=\"${BINARY}\";          LogText \"  Found known binary: rootsh (wrapper for shells) - ${BINARY}\" ;;\n                            rpcinfo)                RPCINFOBINARY=\"${BINARY}\";         LogText \"  Found known binary: rpcinfo (RPC information) - ${BINARY}\" ;;\n                            rpm)                    RPMBINARY=\"${BINARY}\";             LogText \"  Found known binary: rpm (package manager) - ${BINARY}\" ;;\n                            runlevel)               RUNLEVELBINARY=\"${BINARY}\";        LogText \"  Found known binary: runlevel (system utility) - ${BINARY}\" ;;\n                            salt-master)            SALTMASTERBINARY=\"${BINARY}\";      LogText \"  Found known binary: salt-master (SaltStack master) - ${BINARY}\" ;;\n                            salt-minion)            SALTMINIONBINARY=\"${BINARY}\";      LogText \"  Found known binary: salt-minion (SaltStack client) - ${BINARY}\" ;;\n                            samhain)                SAMHAINBINARY=\"${BINARY}\";         LogText \"  Found known binary: samhain (integrity tool) - ${BINARY}\" ;;\n                            service)                SERVICEBINARY=\"${BINARY}\";         LogText \"  Found known binary: service (system services) - ${BINARY}\" ;;\n                            sed)                    SEDBINARY=\"${BINARY}\";             LogText \"  Found known binary: sed (text stream editor) - ${BINARY}\" ;;\n                            semanage)               SEMANAGEBINARY=\"${BINARY}\";        LogText \"  Found known binary: semanage (SELinux policy management tool) - ${BINARY}\" ;;\n                            sestatus)               SESTATUSBINARY=\"${BINARY}\";        LogText \"  Found known binary: sestatus (SELinux status tool) - ${BINARY}\" ;;\n                            slocate)                LOCATEBINARY=\"${BINARY}\";          LogText \"  Found known binary: slocate (file database) - ${BINARY}\" ;;\n                            smbd)                   SMBDBINARY=\"${BINARY}\";            if [ \"${OS}\" = \"macOS\" ]; then SMBDVERSION=\"unknown\"; else SMBDVERSION=$(${BINARY} -V | grep \"^Version\" | awk '{ print $2 }'); fi; LogText \"Found ${BINARY} (version ${SMBDVERSION})\" ;;\n                            smtpctl)                SMTPCTLBINARY=\"${BINARY}\";         LogText \"  Found known binary: smtpctl (OpenSMTPD client) - ${BINARY}\" ;;\n                            showmount)              SHOWMOUNTBINARY=\"${BINARY}\";       LogText \"  Found known binary: showmount (NFS mounts) - ${BINARY}\" ;;\n                            snort)                  SNORTBINARY=\"${BINARY}\";           LogText \"  Found known binary: snort (IDS) - ${BINARY}\" ;;\n                            sockstat)               SOCKSTATBINARY=\"${BINARY}\";        LogText \"  Found known binary: sockstat (open network sockets) - ${BINARY}\" ;;\n                            sort)                   SORTBINARY=\"${BINARY}\";            LogText \"  Found known binary: sort (sort data streams) - ${BINARY}\" ;;\n                            squid)                  SQUIDBINARY=\"${BINARY}\";           LogText \"  Found known binary: squid (proxy) - ${BINARY}\" ;;\n                            ss)                     SSBINARY=\"${BINARY}\";              LogText \"  Found known binary: ss (show sockets) - ${BINARY}\" ;;\n                            sshd)                   SSHDBINARY=\"${BINARY}\";            SSHDVERSION=$(${BINARY} -t -d 2>&1 | grep 'sshd version' | awk '{ print $4 }' | cut -d '_' -f2 | tr -d ',' | tr -d '\\r'); LogText \"Found ${BINARY} (version ${SSHDVERSION})\" ;;\n                            stat)                   STATBINARY=\"${BINARY}\";            LogText \"  Found known binary: stat (file information) - ${BINARY}\" ;;\n                            strings)                STRINGSBINARY=\"${BINARY}\";         LogText \"  Found known binary: strings (text strings search) - ${BINARY}\" ;;\n                            sha1|sha1sum|shasum)    SHA1SUMBINARY=\"${BINARY}\";         LogText \"  Found known binary: sha1/sha1sum/shasum (crypto hashing) - ${BINARY}\" ;;\n                            sha256|sha256sum)       SHA256SUMBINARY=\"${BINARY}\";       LogText \"  Found known binary: sha256/sha256sum (crypto hashing) - ${BINARY}\" ;;\n                            ssh-keyscan)            SSHKEYSCANBINARY=\"${BINARY}\";      LogText \"  Found known binary: ssh-keyscan (scanner for SSH keys) - ${BINARY}\" ;;\n                            suricata)               SURICATABINARY=\"${BINARY}\";        LogText \"  Found known binary: suricata (IDS) - ${BINARY}\" ;;\n                            swapon)                 SWAPONBINARY=\"${BINARY}\";          LogText \"  Found known binary: swapon (swap device tool) - ${BINARY}\" ;;\n                            svcs)                   SVCSBINARY=\"${BINARY}\" ;           LogText \"  Found known binary: svcs (service manager) - ${BINARY}\" ;;\n                            swupd)                  SWUPDBINARY=\"${BINARY}\";           LogText \"  Found known binary: swupd (package manager) - ${BINARY}\" ;;\n                            synoavd)                SYNOAVDBINARY=${BINARY};           LogText \"  Found known binary: synoavd (Synology AV scanner) - ${BINARY}\" ;;\n                            sysctl)                 SYSCTLBINARY=\"${BINARY}\";          LogText \"  Found known binary: sysctl (kernel parameters) - ${BINARY}\" ;;\n                            syslog-ng)              SYSLOGNGBINARY=\"${BINARY}\";        SYSLOGNGVERSION=$(${BINARY} -V 2>&1 | grep \"^syslog-ng\" | awk '{ print $2 }'); LogText \"Found ${BINARY} (version ${SYSLOGNGVERSION})\" ;;\n                            systemctl)              SYSTEMCTLBINARY=\"${BINARY}\";       LogText \"  Found known binary: systemctl (client to systemd) - ${BINARY}\" ;;\n                            systemd-analyze)        SYSTEMDANALYZEBINARY=\"${BINARY}\";  LogText \"  Found known binary: systemd-analyze (systemd service analysis tool) - ${BINARY}\" ;;\n                            tail)                   TAILBINARY=\"${BINARY}\";            LogText \"  Found known binary: tail (text filter) - ${BINARY}\" ;;\n                            timedatectl)            TIMEDATECTL=\"${BINARY}\";           LogText \"  Found known binary: timedatectl (timedate client) - ${BINARY}\" ;;\n                            tomoyo-init)            TOMOYOINITBINARY=${BINARY};        LogText \"  Found known binary: tomoyo-init (tomoyo component) - ${BINARY}\" ;;\n                            tomoyo-pstree)          TOMOYOPSTREEBINARY=${BINARY};      LogText \"  Found known binary: tomoyo-pstree (tomoyo process tree) - ${BINARY}\" ;;\n                            tr)                     TRBINARY=\"${BINARY}\";              LogText \"  Found known binary: tr (text transformation) - ${BINARY}\" ;;\n                            tripwire)               TRIPWIREBINARY=\"${BINARY}\";        LogText \"  Found known binary: tripwire (file integrity) - ${BINARY}\" ;;\n                            tune2fs)                TUNE2FSBINARY=\"${BINARY}\";         LogText \"  Found known binary: tune2fs (file system tool) - ${BINARY}\" ;;\n                            uname)                  UNAMEBINARY=\"${BINARY}\";           LogText \"  Found known binary: uname (operating system details) - ${BINARY}\" ;;\n                            uniq)                   UNIQBINARY=\"${BINARY}\";            LogText \"  Found known binary: uniq (text manipulation utility) - ${BINARY}\";;\n                            usbguard)               USBGUARDBINARY=\"${BINARY}\";        LogText \"  Found known binary: usbguard (USB security tool) - ${BINARY}\" ;;\n                            veritysetup)            VERITYSETUPBINARY=\"${BINARY}\";     LogText \"  Found known binary: veritysetup (dm-verity setup tool) - ${BINARY}\" ;;\n                            vgdisplay)              VGDISPLAYBINARY=\"${BINARY}\";       LogText \"  Found known binary: vgdisplay (LVM tool) - ${BINARY}\" ;;\n                            vmtoolsd)               VMWARETOOLSDBINARY=\"${BINARY}\";    LogText \"  Found known binary: vmtoolsd (VMWare tools) - ${BINARY}\" ;;\n                            wc)                     WCBINARY=\"${BINARY}\";              LogText \"  Found known binary: wc (word count) - ${BINARY}\" ;;\n                            wget)                   WGETBINARY=\"${BINARY}\";            WGETVERSION=$(${BINARY} -V 2> /dev/null | grep \"^GNU Wget\" | awk '{ print $3 }'); LogText \"Found ${BINARY} (version ${WGETVERSION})\" ;;\n                            yum)                    YUMBINARY=\"${BINARY}\";             LogText \"  Found known binary: yum (package manager) - ${BINARY}\" ;;\n                            xargs)                  XARGSBINARY=\"${BINARY}\";           LogText \"  Found known binary: xargs (command output redirection) - ${BINARY}\" ;;\n                            zgrep)                  ZGREPBINARY=${BINARY};             LogText \"  Found known binary: zgrep (text search for compressed files) - ${BINARY}\" ;;\n                            zypper)                 ZYPPERBINARY=\"${BINARY}\";          LogText \"  Found known binary: zypper (package manager) - ${BINARY}\" ;;\n                        esac\n                    done\n                else\n                    LogText \"Result: Directory ${SCANDIR} skipped\"\n                    if [ -n \"${ORGPATH}\" ]; then TEXT=\"${ORGPATH} (links to ${SCANDIR})\"; else TEXT=\"${SCANDIR}\"; fi\n                fi\n            else\n                LogText \"Result: Directory ${SCANDIR} does NOT exist\"\n            fi\n        done\n\n        # unset SORTED_BIN_PATHS\n        BINARY_SCAN_FINISHED=1\n        BINARY_PATHS_FOUND=$(echo ${BINARY_PATHS_FOUND} | sed 's/^, //g' | sed 's/, /,/g')\n        LogText \"Discovered directories: ${BINARY_PATHS_FOUND}\"\n        LogText \"Result: found ${COUNT} binaries including ${NSUID_BINARIES} set-uid and ${NSGID_BINARIES} set-gid\"\n        LogText \"Result: set-uid binaries: ${SUID_BINARIES}\"\n        LogText \"Result: set-gid binaries: ${SGID_BINARIES}\"\n        Report \"binaries_count=${COUNT}\"\n        Report \"binaries_suid_count=${SUID_BINARIES}\"\n        Report \"binaries_sgid_count=${SGID_BINARIES}\"\n        Report \"binary_paths=${BINARY_PATHS_FOUND}\"\n\n\t# If grep is capable of extended regexp, use that instead of egrep to avoid annoying warning\n\tif [ \"${GREPBINARY:-}\" ] ; then\n\t\t${GREPBINARY} --help 2> /dev/null | ${GREPBINARY} -e \"extended-regexp\" > /dev/null\n\t\tif [ $? -eq 0 ] ; then\n\t\t\tEGREPBINARY=\"${GREPBINARY} -E\"\n\t\tfi\n\tfi\n\t\n\n        # Test if the basic system tools are defined. These will be used during the audit.\n        [ \"${AWKBINARY:-}\" ] || ExitFatal \"awk binary not found\"\n        [ \"${CAT_BINARY:-}\" ] || ExitFatal \"cat binary not found\"\n        [ \"${CUTBINARY:-}\" ] || ExitFatal \"cut binary not found\"\n        [ \"${FINDBINARY:-}\" ] || ExitFatal \"find binary not found\"\n        [ \"${GREPBINARY:-}\" ] || ExitFatal \"grep binary not found\"\n        [ \"${HEADBINARY:-}\" ] || ExitFatal \"head binary not found\"\n        [ \"${TAILBINARY:-}\" ] || ExitFatal \"tail binary not found\"\n        [ \"${LSBINARY:-}\" ] || ExitFatal \"ls binary not found\"\n        [ \"${PSBINARY:-}\" ] || ExitFatal \"ps binary not found\"\n        [ \"${SEDBINARY:-}\" ] || ExitFatal \"sed binary not found\"\n        [ \"${SORTBINARY:-}\" ] || ExitFatal \"sort binary not found\"\n        [ \"${TRBINARY:-}\" ] || ExitFatal \"tr binary not found\"\n        [ \"${UNIQBINARY:-}\" ] || ExitFatal \"uniq binary not found\"\n        [ \"${WCBINARY:-}\" ] || ExitFatal \"wc binary not found\"\n\n        # Test a few other tools that we did not specifically define (yet)\n        #TOOLS=\"xxd\"\n        #for T in ${TOOLS}; do\n        #    DATA=$(type ${T})\n        #    if [ $? -gt 0 ]; then ExitFatal \"${T} binary not found\"; fi\n        #done\n\n    else\n        LogText \"Result: checking of binaries skipped in this mode\"\n    fi\n\n\n# EOF\n"
  },
  {
    "path": "include/consts",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Consts\n#\n#################################################################################\n#\n\n# Paths where system and program binaries are typically located\nBIN_PATHS=\"/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin \\\n          /usr/local/libexec /usr/libexec \\\n          /usr/sfw/bin /usr/sfw/sbin /usr/sfw/libexec \\\n          /opt/sfw/bin /opt/sfw/sbin /opt/sfw/libexec \\\n          /usr/xpg4/bin /usr/css/bin /usr/ucb /usr/X11R6/bin /usr/X11R7/bin \\\n          /usr/pkg/bin /usr/pkg/sbin /usr/gnu/bin\"\n\nETC_PATHS=\"/etc /usr/local/etc\"\n\n#\n#################################################################################\n#\n# Initialize defaults\n#\n#################################################################################\n#\n# == Variable initializing ==\n#\n    APTBINARY=\"\"\n    APKBINARY=\"\"\n    ARCH_AUDIT_BINARY=\"\"\n    AUDITORNAME=\"\"\n    AUDITCTLBINARY=\"\"\n    AUDITDBINARY=\"\"\n    AUTH_FAILED_LOGINS_LOGGED=0\n    AUTH_UNLOCK_TIME=-1\n    PROFILE=\"\"\n    REPORTFILE=\"\"\n    AFICKBINARY=\"\"\n    AIDEBINARY=\"\"\n    AASTATUSBINARY=\"\"\n    AUDITD_RUNNING=0\n    APPLICATION_FIREWALL_ACTIVE=0\n    BINARY_SCAN_FINISHED=0\n    BLKIDBINARY=\"\"\n    BOOTCTLBINARY=\"\"\n    CAT_BINARY=\"\"\n    CCBINARY=\"\"\n    CFAGENTBINARY=\"\"\n    CHECK=0\n    CHECK_BINARIES=1\n    CHECK_OPTION_ARRAY=\"\"\n    CHKROOTKITBINARY=\"\"\n    CHKCONFIGBINARY=\"\"\n    CLAMCONF_BINARY=\"\"\n    CLAMSCANBINARY=\"\"\n    CLANGBINARY=\"\"\n    CMDBINARY=\"\"\n    COLORS=1\n    COMPLIANCE_ENABLE_CIS=0\n    COMPLIANCE_ENABLE_HIPAA=0\n    COMPLIANCE_ENABLE_ISO27001=0\n    COMPLIANCE_ENABLE_PCI_DSS=0\n    COMPLIANCE_TESTS_PERFORMED=0\n    COMPLIANCE_FINDINGS_FOUND=0\n    COMPRESSED_UPLOADS=0\n    CONTROL_URL_APPEND=\"\"\n    CONTROL_URL_PREPEND=\"\"\n    CONTROL_URL_PROTOCOL=\"\"\n    CONTAINER_TYPE=\"\"\n    CREATE_REPORT_FILE=1\n    CRYPTSETUPBINARY=\"\"\n    CSUMBINARY=\"\"\n    CURRENT_TS=0\n    CUSTOM_URL_APPEND=\"\"\n    CUSTOM_URL_PREPEND=\"\"\n    CUSTOM_URL_PROTOCOL=\"\"\n    CUTBINARY=\"\"\n    DATABASE_ENGINE_RUNNING=0\n    DB2_RUNNING=0\n    DBUSDAEMONBINARY=\"\"\n    DEBSECANBINARY=\"\"\n    DEBSUMSBINARY=\"\"\n    DEVELOPER_MODE=0\n    DEVOPS_MODE=0\n    DIGBINARY=\"\"\n    DISABLED_PLUGINS=\"\"\n    DISCOVERED_BINARIES=\"\"\n    DMIDECODEBINARY=\"\"\n    DNFBINARY=\"\"\n    DNSDOMAINNAMEBINARY=\"\"\n    DOCKERBINARY=\"\"\n    DOCKER_DAEMON_RUNNING=0\n    DPKGBINARY=\"\"\n    ECHOCMD=\"\"\n    ERROR_ON_WARNINGS=0\n    EQUERYBINARY=\"\"\n    EVMCTLBINARY=\"\"\n    EXIMBINARY=\"\"\n    FAIL2BANBINARY=\"\"\n    FILEBINARY=\"\"\n    FILEVALUE=\"\"\n    FIND=\"\"\n    FIREWALL_ACTIVE=0\n    FOUNDPATH=0\n    FORENSICS_MODE=0\n    GCCBINARY=\"\"\n    GETENT_BINARY=\"\"\n    GRADMBINARY=\"\"\n    GREPBINARY=\"grep\"\n    GROUP_NAME=\"\"\n    GRPCKBINARY=\"\"\n    GRSEC_FOUND=0\n    GRUBCONFFILE=\"\"\n    GRUB2INSTALLBINARY=\"\"\n    HAS_PACKAGE_MANAGER=0\n    HAS_SYSTEMD=0\n    HEADBINARY=\"\"\n    HELPER=\"\"\n    HOSTID=\"\"\n    HOSTID_GEN=\"unknown\"\n    HOSTID2=\"\"\n    HOSTID2_GEN=\"unknown\"\n    HTTPDBINARY=\"\"\n    IDS_IPS_TOOL_FOUND=0\n    IFCONFIGBINARY=\"\"\n    INTEGRITYSETUPBINARY=\"\"\n    IPBINARY=\"\"\n    IPFBINARY=\"\"\n    IPTABLESBINARY=\"\"\n    JOURNALCTLBINARY=\"\"\n    KADMINLOCALBINARY=\"\"\n    KLDSTATBINARY=\"\"\n    LAUNCHCTL_BINARY=\"\"\n    LDAP_CLIENT_CONFIG_FILE=\"\"\n    LICENSE_KEY=\"\"\n    LICENSE_SERVER=\"\"\n    LINUX_VERSION=\"\"\n    LINUX_VERSION_LIKE=\"\"\n    LINUXCONFIGFILE=\"\"\n    LMDBINARY=\"\"\n    LMDFOUND=0\n    LOCATEBINARY=\"\"\n    LOGFILE=\"\"\n    LOGDIR=\"\"\n    LOGROTATEBINARY=\"\"\n    LOGTEXT=1\n    LSBLKBINARY=\"\"\n    LSMODBINARY=\"\"\n    LSOFBINARY=\"\"\n    LSOF_EXTRA_OPTIONS=\"\"\n    LSVGBINARY=\"\"\n    LYNIS_CRONJOB=\"\"\n    MACHINEID=\"\"\n    MACHINE_ROLE=\"\"\n    MALWARE_SCANNER_INSTALLED=0\n    MDATPBINARY=\"\"\n    MIN_PASSWORD_LENGTH=-1\n    MONGODB_RUNNING=0\n    MONOLITHIC_KERNEL_TESTED=0\n    MOUNTBINARY=\"\"\n    MTREEBINARY=\"\"\n    MYSQLCLIENTBINARY=\"\"\n    MYSQL_RUNNING=0\n    N_PLUGIN=0\n    N_PLUGIN_ENABLED=0\n    NAME_CACHE_USED=0\n    NETWORK_INTERFACES=\"\"\n    NFTBINARY=\"\"\n    NGINX_ACCESS_LOG_DISABLED=0\n    NGINX_ACCESS_LOG_MISSING=0\n    NGINX_ALIAS_FOUND=0\n    NGINX_ALLOW_FOUND=0\n    NGINX_DENY_FOUND=0\n    NGINX_ERROR_LOG_DEBUG=0\n    NGINX_ERROR_LOG_MISSING=0\n    NGINX_EVENTS_COUNTER=0\n    NGINX_EXPIRES_FOUND=0\n    NGINX_FASTCGI_FOUND=0\n    NGINX_FASTCGI_PARAMS_FOUND=0\n    NGINX_FASTCGI_PASS_FOUND=0\n    NGINX_HTTP_COUNTER=0\n    NGINX_LISTEN_FOUND=0\n    NGINX_LOCATION_COUNTER=0\n    NGINX_LOCATION_FOUND=0\n    NGINX_SERVER_COUNTER=0\n    NGINX_SSL_CIPHERS=0\n    NGINX_SSL_ON=0\n    NGINX_SSL_PREFER_SERVER_CIPHERS=0\n    NGINX_SSL_PROTOCOLS=0\n    NGINX_RETURN_FOUND=0\n    NGINX_ROOT_FOUND=0\n    NGINX_WEAK_SSL_PROTOCOL_FOUND=0\n    NTPCTLBINARY=\"\"\n    NTPD_ROLE=\"\"\n    NTPQBINARY=\"\"\n    OPENSSLBINARY=\"\"\n    OPTION_DEBIAN_SKIP_SECURITY_REPOSITORY=0\n    OPTIONS_CONN_MAX_WAIT_STATE=\"\"\n    ORACLE_RUNNING=0\n    OS=\"\"\n    OS_KERNELVERSION=\"\"\n    OS_KERNELVERSION_FULL=\"\"\n    OS_MODE=\"\"\n    OS_REDHAT_OR_CLONE=0\n    OSIRISBINARY=\"\"\n    PACMANBINARY=\"\"\n    PAM_PASSWORD_PWHISTORY_AMOUNT=\"\"\n    PASSWORD_MAXIMUM_DAYS=-1\n    PASSWORD_MINIMUM_DAYS=-1\n    PAM_2F_AUTH_ENABLED=0\n    PAM_2F_AUTH_REQUIRED=0\n    PAM_AUTH_BRUTE_FORCE_PROTECTION=0\n    PAM_PASSWORD_HISTORY_AMOUNT=0\n    PAM_PASSWORD_HISTORY_ENABLED=0\n    PAM_PASSWORD_STRENGTH_TESTED=0\n    PAM_PASSWORD_PWHISTORY_ENABLED=0\n    PAM_PASSWORD_UXHISTORY_ENABLED=0\n    PFCTLBINARY=\"\"\n    PFFOUND=0\n    PGREPBINARY=\"\"\n    PIDFILE=\"\"\n    PKG_BINARY=\"\"\n    PKGINFOBINARY=\"\"\n    PKGADMINBINARY=\"\"\n    PLUGINDIR=\"\"\n    PLUGIN_PHASE=0\n    POSTFIXBINARY=\"\"\n    POSTGRESQL_RUNNING=0\n    PREVIOUS_TEST=\"No test ID\"\n    PREVIOUS_TS=0\n    PROFILES=\"\"\n    PROFILEVALUE=\"\"\n    PSBINARY=\"ps\"\n    PSOPTIONS=\"\"\n    PUPPETBINARY=\"\"\n    QNAP_DEVICE=0\n    READLINKBINARY=\"\"\n    REDIS_RUNNING=0\n    REFRESH_REPOSITORIES=1\n    REMOTE_LOGGING_ENABLED=0\n    RESOLV_DOMAINNAME=\"\"\n    RESOLVECTLBINARY=\"\"\n    RKHUNTERBINARY=\"\"\n    ROOTDIR=\"/\"\n    ROOTSHBINARY=\"\"\n    RPCINFOBINARY=\"\"\n    RPMBINARY=\"\"\n    RUN_HELPERS=0\n    RUN_TESTS=1\n    RUN_UPDATE_CHECK=1\n    SALTMASTERBINARY=\"\"\n    SALTMINIONBINARY=\"\"\n    SAMHAINBINARY=\"\"\n    SCAN_TEST_HEAVY=\"\"; SCAN_TEST_MEDIUM=\"\"; SCAN_TEST_LOW=\"\"\n    SEARCH_PROFILES=\"\"\n    SEARCH_VERSION=\"\"\n    SESTATUSBINARY=\"\"\n    SERVICE_MANAGER=\"\"\n    SETBINARY=\"\"\n    SETTINGS=\"\"\n    SETTINGS_FILE=\"\"\n    SET_STRICT=0\n    SHA1SUMBINARY=\"\"\n    SHA256SUMBINARY=\"\"\n    SHELL_IS_BUSYBOX=0\n    SHOWMOUNTBINARY=\"\"\n    SHOW_PROGRAM_DETAILS=1\n    SHOW_REPORT=1\n    SHOW_REPORT_SOLUTION=1\n    SHOW_TOOL_TIPS=1                    # Show inline tool tips (default true)\n    SHOW_WARNINGS_ONLY=0\n    SKIP_GETHOSTID=0\n    SKIP_PLUGINS=0\n    SKIP_TESTS=\"\"\n    SKIP_VM_DETECTION=0\n    SKIPREASON=\"\"\n    SKIPPED_TESTS_ROOTONLY=\"\"\n    SLOW_TEST_THRESHOLD=10\n    SMTPCTLBINARY=\"\"\n    SNORTBINARY=\"\"\n    SSBINARY=\"\"\n    SSHKEYSCANBINARY=\"\"\n    SSHKEYSCANFOUND=0\n    SSL_CERTIFICATE_INCLUDE_PACKAGES=0\n    SSL_CERTIFICATE_PATHS=\"\"\n    SSL_CERTIFICATE_PATHS_TO_IGNORE=\"\"\n    STATUS_NOT_ACTIVE=\"\"\n    STUNNELBINARY=\"\"\n    SURICATABINARY=\"\"\n    SWUPDBINARY=\"\"\n    SYSLOGNGBINARY=\"\"\n    SYSTEMCTLBINARY=\"\"\n    SYSTEMDANALYZEBINARY=\"\"\n    SYSTEM_IS_NOTEBOOK=255\n    TEMP_FILE=\"\"\n    TEMP_FILES=\"\"\n    TEST_SKIP_ALWAYS=\"\"\n    TEST_AVAILABLE_CATEGORIES=\"performance privacy security\"\n    TEST_CATEGORY_TO_CHECK=\"all\"\n    TEST_GROUP_TO_CHECK=\"all\"\n    TESTS_EXECUTED=\"\"\n    TESTS_SKIPPED=\"\"\n    TIMEDATECTL=\"\"\n    TMPFILE=\"\"\n    TOMOYOINITBINARY=\"\"\n    TOOLTIP_SHOWED=0\n    TOTAL_SUGGESTIONS=0\n    TOTAL_WARNINGS=0\n    TRBINARY=\"\"\n    TRIPWIREBINARY=\"\"\n    UEFI_BOOTED=0\n    UEFI_BOOTED_SECURE=0\n    UNAMEBINARY=\"\"\n    UNBOUND_RUNNING=0\n    UNIQBINARY=\"\"\n    UPDATE_CHECK_SKIPPED=0\n    UPLOAD_OPTIONS=\"\"\n    UPLOAD_PROXY_PORT=\"\"\n    UPLOAD_PROXY_PROTOCOL=\"\"\n    UPLOAD_PROXY_SERVER=\"\"\n    UPLOAD_SERVER=\"\"\n    UPLOAD_TOOL=\"\"\n    UPLOAD_TOOL_ARGS=\"\"\n    USBGUARDBINARY=\"\"\n    USBGUARD_CONFIG=\"\"\n    USBGUARD_ROOT=\"\"\n    VALUE=\"\"\n    VERBOSE=0\n    VERITYSETUPBINARY=\"\"\n    VGDISPLAYBINARY=\"\"\n    VMTYPE=\"\"\n    VULNERABLE_PACKAGES_FOUND=0\n    WCBINARY=\"\"\n    XARGSBINARY=\"\"\n    XBPSBINARY=\"\"\n    YUMBINARY=\"\"\n    ZYPPERBINARY=\"\"\n\n#\n#################################################################################\n#\n# * Options\n#\n#################################################################################\n#\n    CRONJOB=0                   # Run as a cronjob\n    CTESTS_PERFORMED=0          # Number of tests which are performed\n    DEBUG=0                     # Debugging mode (to screen)\n    HPPOINTS=0                  # Number of hardening points\n    HPTOTAL=0                   # Maximum number of hardening points\n    LOG_INCORRECT_OS=1          # Log tests with incorrect OS\n    NEVERBREAK=0                # Don't wait for user input\n    QUICKMODE=1                 # Don't wait for user input\n    QUIET=0                     # Show normal messages and warnings as well\n    SKIPLOGTEST=0               # Skip logging for one test\n    SKIP_UPGRADE_TEST=0         # Skip upgrade test\n    TESTS_TO_PERFORM=\"\"         # Which tests only to perform\n    TEST_PAUSE_TIME=0           # Default pause time\n    TOTAL_TESTS=0               # Total amount of tests (counter)\n    UPLOAD_DATA=0               # Upload of data to central node\n    VIEWHELP=0                  # Show help\n    WRONGOPTION=0               # A wrong option is used\n#\n#################################################################################\n#\n    # Installed packages and other settings\n    COMPILER_INSTALLED=0\n#\n#################################################################################\n#\n# * Colors\n#\n# For improved display\n#\n#################################################################################\n#\n\n    # Normal color names (BG will color background)\n    BG_BLUE=\"$(printf '\\033[0;44m')\"\n    CYAN=\"$(printf '\\033[0;36m')\"\n    BLUE=\"$(printf '\\033[0;34m')\"\n    BROWN=\"$(printf '\\033[0;33m')\"\n    DARKGRAY=\"$(printf '\\033[0;30m')\"\n    GRAY=\"$(printf '\\033[0;37m')\"\n    GREEN=\"$(printf '\\033[1;32m')\"\n    LIGHTBLUE=\"$(printf '\\033[0;94m')\"\n    MAGENTA=\"$(printf '\\033[1;35m')\"\n    PURPLE=\"$(printf '\\033[0;35m')\"\n    RED=\"$(printf '\\033[1;31m')\"\n    YELLOW=\"$(printf '\\033[1;33m')\"\n    WHITE=\"$(printf '\\033[1;37m')\"\n\n    # Special markup\n    BOLD=\"${WHITE}\"\n    NORMAL=\"$(printf '\\033[0m')\"\n\n    # Semantic names\n    BG_WARNING=\"$(printf '\\033[30;43m')\"  # Yellow background with grey text\n    HEADER=\"${WHITE}\"\n    WARNING=\"${RED}\"\n    SECTION=\"${YELLOW}\"\n    NOTICE=\"${YELLOW}\"\n    OK=\"${GREEN}\"\n    BAD=\"${RED}\"\n\n# EOF \n"
  },
  {
    "path": "include/data_upload",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Data upload\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_DATA_UPLOAD}\"\n\n    PROGRAM_VERSION=\"105\"\n\n    # Data upload destination\n    if [ \"${UPLOAD_SERVER}\" = \"\" ]; then UPLOAD_SERVER=\"portal.cisofy.com\"; fi\n    UPLOAD_URL=\"https://${UPLOAD_SERVER}/upload/\"\n    LogText \"Upload server: ${UPLOAD_SERVER}\"\n    LogText \"URL to upload to: ${UPLOAD_URL}\"\n\n    # License server (set to upload server if not configured)\n    if [ \"${LICENSE_SERVER}\" = \"\" ]; then LICENSE_SERVER=\"${UPLOAD_SERVER}\"; fi\n    LICENSE_SERVER_URL=\"https://${LICENSE_SERVER}/license/\"\n    LogText \"License server: ${LICENSE_SERVER}\"\n\n    # Additional options to curl\n    if [ \"${UPLOAD_OPTIONS}\" = \"\" ]; then\n        CURL_OPTIONS=\"\"\n    else\n        CURL_OPTIONS=\" ${UPLOAD_OPTIONS}\"\n    fi\n\n    SETTINGS_FILE=\"${PROFILE}\"\n    #if [ \"${UPLOAD_TOOL}\" = \"\" ]; then UPLOAD_TOOL=\"${CURLBINARY}\"; fi\n\n    # Only output text to stdout if DEBUG mode is not used\n    Output() {\n        if [ ${DEBUG} -eq 1 ]; then echo \"$1\"; fi\n    }\n\n#####################################################################################\n#\n# SYSTEM CHECKS\n#\n#####################################################################################\n\n    Output \"Lynis Enterprise data uploader starting\"\n    Output \"Settings file: ${SETTINGS_FILE}\"\n\n    # Check if we can find curl\n    # Suggestion: If you want to keep the system hardened, copying the binary from a trusted source is a good alternative.\n    #             Restrict access to this binary to the user who is running this script.\n    if IsEmpty \"${CURLBINARY}\"; then\n        echo \"Fatal: can't find curl binary. Please install the related package or put the binary in the PATH. Quitting..\"\n        LogText \"Error: Could not find cURL binary\"\n        exit 1\n    fi\n\n    # Extra the license key from the settings file\n    if [ \"${LICENSE_KEY}\" = \"\" ]; then\n        echo \"Fatal: no license key found. Quitting..\"\n        LogText \"Error: no license key was specified in the profile (${PROFILE})\"\n        ExitFatal\n    else\n        Output \"License key = ${LICENSE_KEY}\"\n        # Create a temporary file to use during upload (prevent license key being displayed in process table)\n        CreateTempFile || ExitFatal\n        LICENSE_KEY_FILE=\"${TEMP_FILE}\"\n        echo \"${LICENSE_KEY}\" | ${TRBINARY} -cd '[a-f0-9-]' > ${LICENSE_KEY_FILE}\n    fi\n\n\n#####################################################################################\n#\n# JOB CONTROL\n#\n#####################################################################################\n\n\n    # Check report file\n    if [ -f ${REPORTFILE} ]; then\n\n        Output \"${WHITE}Report file found.${NORMAL} Starting with content check.\"\n\n        FIND=$(${GREPBINARY} \"finish=true\" ${REPORTFILE})\n        if [ $? -gt 0 ]; then ExitFatal \"The report is not complete, skipping upload\"; fi\n\n        Output \"${WHITE}Report file found.${NORMAL} Starting with connectivity check.\"\n\n            if [ ! \"${UPLOAD_PROXY_SERVER}\" = \"\" ]; then\n                LogText \"Upload: Proxy is configured: ${UPLOAD_SERVER}\"\n                # Port is optional\n                if [ ! \"${UPLOAD_PROXY_PORT}\" = \"\" ]; then\n                    LogText \"Upload: Proxy port number is ${UPLOAD_PROXY_PORT}\"\n                    UPLOAD_PROXY_PORT=\":${UPLOAD_PROXY_PORT}\"\n                fi\n                LogText \"Upload: Proxy protocol is ${UPLOAD_PROXY_PROTOCOL}\"\n                case ${UPLOAD_PROXY_PROTOCOL} in\n                    \"http\"|\"https\")\n                        UPLOAD_PROXY=\"${UPLOAD_PROXY_PROTOCOL}://${UPLOAD_PROXY_SERVER}${UPLOAD_PROXY_PORT}\"\n                        CURL_OPTIONS=\"${CURL_OPTIONS} --proxy ${UPLOAD_PROXY}\"\n                    ;;\n                    \"socks5\")\n                        UPLOAD_PROXY=\"${UPLOAD_PROXY_SERVER}${UPLOAD_PROXY_PORT}\"\n                        CURL_OPTIONS=\"${CURL_OPTIONS} --socks5 ${UPLOAD_PROXY}\"\n                    ;;\n                    *)\n                        echo \"Unknown protocol. Please report to lynis-dev@cisofy.com\"\n                        ExitFatal\n                    ;;\n                esac\n            fi\n\n            # Currently compressed uploads are not supported yet on central node. Therefore default value is set to 0.\n            #if [ ${COMPRESSED_UPLOADS} -eq 1 ]; then\n            #    CURL_OPTIONS=\"${CURL_OPTIONS} --compressed -H 'Content-Encoding: gzip'\"\n            #fi\n\n\n        # License check\n\n        LogText \"Command used: ${CURLBINARY}${CURL_OPTIONS} -s -S --data-urlencode \"licensekey@${LICENSE_KEY_FILE}\" --data-urlencode \"collector_version=${PROGRAM_VERSION}\" ${LICENSE_SERVER_URL} 2> /dev/null\"\n        UPLOAD=$(${CURLBINARY}${CURL_OPTIONS} -s -S --data-urlencode \"licensekey@${LICENSE_KEY_FILE}\" --data-urlencode \"collector_version=${PROGRAM_VERSION}\" ${LICENSE_SERVER_URL} 2> /dev/null)\n\n        EXITCODE=$?\n        LogText \"Exit code: ${EXITCODE}\"\n        if [ ${EXITCODE} -gt 0 ]; then\n\n            Display --indent 2 --text \"- License check\" --result \"FAILED\" --color RED\n\n            echo \"\"\n\n            case ${EXITCODE} in\n                    2)\n                        LogText \"Result: could not initialize\"\n                        LogText \"Possible cause: most likely your cURL version is too old and does not support the --data-urlencode option.\"\n                        LogText \"Suggestion: copy the data to a different server and use a new cURL version there, or use the Lynis Collector tool.\"\n                        echo \"${RED}Error (2)${NORMAL}: could not initialize cURL.\"\n                        ;;\n                    5)\n                        LogText \"Result: could not resolve the defined proxy server (${UPLOAD_PROXY_SERVER}).\"\n                        LogText \"Suggestion: check if the proxy is properly defined in the profile.\"\n                        echo \"${RED}Error (5)${NORMAL}: could not use the defined proxy (${UPLOAD_PROXY_SERVER}). See ${LOGFILE} for details.\"\n                        ;;\n                    6)\n                        echo \"${RED}Error (6)${NORMAL}: Could not resolve the hostname of central server.\"\n                        ;;\n                    7)\n                        LogText \"Result: could not contact license server.\"\n                        LogText \"Details: used URL ${LICENSE_SERVER_URL}\"\n                        LogText \"Suggestion: check if the upload host is correctly configured.\"\n                        echo \"${RED}Error (7)${NORMAL}: license server not available.\"\n                        ;;\n                    59)\n                        echo \"${RED}Error (59)${NORMAL}: Could not connect because of used SSL cipher.\"\n                        LogText \"Result: SSL cipher used is not understood or accepted.\"\n                        ;;\n                    60)\n                        echo \"${RED}Error (60)${NORMAL}: Self-signed certificate used on Lynis Enterprise node${NORMAL}\"\n                        echo \"If you want to accept a self-signed certificate, configure your profile and set the -k option in the upload-options.\"\n                        echo \"Example: ${WHITE}$0 configure settings upload-options=-k${NORMAL}\"\n                        LogText \"Result: found self-signed certificate, however cURL -k option not used.\"\n                        ;;\n                    77)\n                        echo \"${YELLOW}Error (77)${NORMAL}: Could not use CA certificates to check certificate chain. See ${LOGFILE} for details.\"\n                        LogText \"Result: could not use CA certificates to check certificate chain\"\n                        LogText \"Possible cause: missing CA certificates, or no permissions to access them\"\n                        LogText \"Suggestion: update your ca-certificates package. Usually updating your packages already solves the issue with missing CA certificates.\"\n                        ;;\n                    83)\n                        echo \"${YELLOW}Error (83)${NORMAL}: Could not check used certificate of server. See ${LOGFILE} for details.\" ;;\n                    *)\n                        echo \"${RED}Upload Error: ${NORMAL}cURL exited with code ${EXITCODE}. See ${LOGFILE} for details.\"\n                        LogText \"Result: cURL exited with code ${EXITCODE}. See man page of cURL for the meaning of this code.\"\n                        ;;\n            esac\n\n            echo \"\"\n            echo \"${RED}Upload Error${NORMAL}: License could not be checked. See ${LOGFILE} for details.\"\n            echo \"Suggested command: tail -n 20 ${LOGFILE}\"\n            echo \"\"\n\n            LogText \"Suggestion: run the cURL command manually without the options -s and -S\"\n            LogText \"Result: quitting, can't check license\"\n            # Quit if license is not valid, to reduce load on both client and server.\n            ExitFatal\n        fi\n\n        UPLOAD_CODE=$(echo ${UPLOAD} | head -n 1 | awk '{ if ($1==\"Response\") { print $2 }}')\n        if [ \"${UPLOAD_CODE}\" = \"100\" ]; then\n            Output \"${WHITE}License is valid${NORMAL}\"\n            LogText \"Result: license is valid\"\n            Display --indent 2 --text \"- License check\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            LogText \"Result: error while checking license\"\n            LogText \"Output: ${UPLOAD_CODE}\"\n            echo \"${RED}Fatal error: ${WHITE}Error while checking the license.${NORMAL}\"\n            echo \"\"\n            echo \"Possible causes and steps you can take:\"\n            echo \"- Connection with license server could not be established (try address in your web browser)\"\n            echo \"- Incorrect server has been configured in profile\"\n            echo \"- License is expired (listed in Configuration screen) or No credits left (listed in Configuration screen)\"\n            echo \"- Collector version of Lynis version outdated (upgrade to latest version of Lynis and/or Lynis Collector)\"\n            echo \"\"\n            echo \"If you need support in solving this, please contact support@cisofy.com and include this screen output.\"\n            echo \"\"\n            echo \"URL: ${LICENSE_SERVER_URL}\"\n            echo \"Key: ${LICENSE_KEY}\"\n            Output \"Debug information: ${UPLOAD}\"\n            # Quit\n            ExitFatal\n        fi\n\n        # Check for host IDs\n        if [ -n \"${HOSTID}\" -a -n \"${HOSTID2}\" ]; then\n            Output \"${WHITE}Found hostid: ${HOSTID}${NORMAL}\"\n            # Try to connect\n            Output \"Uploading data..\"\n            LogText \"Command used: ${CURLBINARY}${CURL_OPTIONS} -s -S --data-urlencode \\\"data@${REPORTFILE}\\\" --data-urlencode \\\"licensekey@${LICENSE_KEY_FILE}\\\" --data-urlencode \\\"hostid=${HOSTID}\\\" ${UPLOAD_URL}\"\n            LogText \"Tip: try running ${CURLBINARY}${CURL_OPTIONS} --data-urlencode \\\"data@${REPORTFILE}\\\" --data-urlencode \\\"licensekey@${LICENSE_KEY_FILE}\\\" --data-urlencode \\\"hostid=${HOSTID}\\\" ${UPLOAD_URL}\"\n            LogText \"Tip: to just retry an upload, use: lynis upload-only\"\n            UPLOAD=$(${CURLBINARY}${CURL_OPTIONS} -s -S --data-urlencode \"data@${REPORTFILE}\" --data-urlencode \"licensekey@${LICENSE_KEY_FILE}\" --data-urlencode \"hostid=${HOSTID}\" --data-urlencode \"hostid2=${HOSTID2}\" ${UPLOAD_URL} 2> /dev/null)\n            EXITCODE=$?\n            LogText \"Exit code: ${EXITCODE}\"\n            if [ ${EXITCODE} -gt 0 ]; then\n                Display --indent 2 --text \"- Data upload (${UPLOAD_SERVER})\" --result \"${STATUS_FAILED}\" --color RED\n\n                echo \"\"\n                echo \"${RED}Upload Error${NORMAL}: cURL could not upload data. See ${LOGFILE} for details.\"\n                echo \"Suggested command: tail -n 20 ${LOGFILE}\"\n                echo \"\"\n                case ${EXITCODE} in\n                    5) echo \"${YELLOW}Error (5): ${NORMAL}Could not resolve the hostname of the proxy.\" ;;\n                    6) echo \"${YELLOW}Error (6): ${NORMAL}Could not resolve the hostname of central server.\" ;;\n                    7) echo \"${YELLOW}Error (7): ${NORMAL}Could not connect to central server or proxy server.\" ;;\n                    59) echo \"${YELLOW}Error (59): ${NORMAL}Could not connect because of used SSL cipher.\" ;;\n                    83) echo \"${YELLOW}Error (83): ${NORMAL}Could not check used certificate of server.\" ;;\n                    *) echo \"Related exit code: ${YELLOW}${EXITCODE}${NORMAL}. See man page of cURL for the meaning of this code.\" ;;\n                esac\n                if [ ! \"${UPLOAD}\" = \"\" ]; then echo \"\"; echo \"Debug:\"; echo ${UPLOAD}; fi\n                echo \"\"\n                # Quit\n                ExitClean\n            else\n                Display --indent 2 --text \"- Data upload (${UPLOAD_SERVER})\" --result \"${STATUS_DONE}\" --color GREEN\n            fi\n        else\n            echo \"${RED}Error${NORMAL}: No hostid and/or hostid2 found. Can not upload report file.\"\n            echo \"Suggested command: lynis generate hostids --save\"\n            echo \"\"\n            echo \"Note: do not replicate the values to other systems, as it needs to be unique per system\"\n\n            # Quit\n            ExitFatal\n        fi\n    else\n         Output \"${YELLOW}No report file found to upload.${NORMAL}\"\n         ExitFatal\n    fi\n\n# EOF\n"
  },
  {
    "path": "include/functions",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Functions\n#\n#################################################################################\n#\n#    Function                   Description\n#    -----------------------    -------------------------------------------------\n#    AddHP                      Add Hardening points to plot a graph later\n#    AddSetting                 Addition of setting\n#    AddSystemGroup             Adds a system to a group\n#    CheckFilePermissions       Check file permissions\n#    CheckItem                  Test for presence of a string in report file\n#    CheckUpdates               Determine if a new version of Lynis is available\n#    CleanUp                    Clean up files before closing program\n#    CountTests                 Count number of performed tests\n#    ContainsString             Find the needle (string) in the haystack (another string)\n#    CreateTempFile             Create a temporary file\n#    Debug                      Display additional information on the screen (not suited for cronjob)\n#    DigitsOnly                 Return only the digits from a string\n#    DirectoryExists            Check if a directory exists on the disk\n#    DiscoverProfiles           Determine available profiles on system\n#    Display                    Output text to screen with colors and indentation\n#    DisplayError               Show an error on screen\n#    DisplayException           Show an exception on screen\n#    DisplayManual              Output text to screen without any layout\n#    DisplayToolTip             Show a tip for improving usage of the tool\n#    DisplayWarning             Show a clear warning on screen\n#    Equals                     Compares two strings\n#    ExitClean                  Stop the program (cleanly), with exit code 0\n#    ExitCustom                 Stop the program (cleanly), with custom exit code\n#    ExitFatal                  Stop the program (cleanly), with exit code 1\n#    FileExists                 Check if a file exists on the disk\n#    FileInstalledByPackage     Check if a file is linked to a package\n#    FileIsEmpty                Check if a file is empty\n#    FileIsReadable             Check if a file is readable or directory accessible\n#    GetHostID                  Retrieve an unique ID for this host\n#    GetReportData              Request data from report\n#    HasCorrectFilePermissions  Check file permissions and see if they match expected values\n#    HasData                    Checks for data in variable\n#    InsertSection              Insert a section block\n#    InsertPluginSection        Insert a section block for plugins\n#    IsContainer                Determine if program runs in a container\n#    IsDebug                    Check if --debug is used\n#    IsDeveloperMode            Check if --developer is used\n#    IsDeveloperVersion         Check if program is a developer release\n#    IsEmpty                    Check for empty result or variable\n#    IsNotebook                 System detection\n#    IsOwnedByRoot              Determine if file or directory is owned by root\n#    IsRunning                  Check if a process is running\n#    IsVerbose                  Check if --verbose is used\n#    IsVirtualMachine           Check if this system is a virtual machine\n#    IsWorldExecutable          Check if a file is world executable\n#    IsWorldReadable            Check if a file is world readable\n#    IsWorldWritable            Check if a file is world writable\n#    LogText                    Log text strings to logfile, prefixed with date/time\n#    LogTextBreak               Insert a separator in log file\n#    PackageIsInstalled         Test for installed package\n#    ParseNginx                 Parse nginx configuration lines\n#    ParseProfiles              Parse all available profiles\n#    ParseTestValues            Parse a set of values\n#    PortIsListening            Check if machine is listening on specified protocol and port\n#    Progress                   Show progress on screen\n#    Readonly                   Mark a variable as read-only data\n#    Register                   Register a test (for logging and execution)\n#    RandomString               Show a random string\n#    RemoveColors               Reset all colors\n#    RemovePIDFile              Remove PID file\n#    RemoveTempFiles            Remove temporary files\n#    Report                     Add string of data to report file\n#    ReportDetails              Store details of tests which include smaller atomic tests in report\n#    ReportException            Add an exception to the report file (for debugging purposes)\n#    ReportManual               Log manual actions to report file\n#    ReportSuggestion           Add a suggestion to report file\n#    ReportWarning              Add a warning and priority to report file\n#    SafeFile                   Security tests to perform on a file before using it\n#    SafePerms                  Check if a file has safe permissions\n#    SafeInput                  Test provided string to see if it contains unwanted characters\n#    SearchItem                 Search a string in a file\n#    ShowComplianceFinding      Display a particular finding regarding compliance or a security standard\n#    ShowSymlinkPath            Show a path behind a symlink\n#    SkipAtomicTest             Test if a subtest needs to be skipped\n#    Status                     Show execution status, such as active test being performed\n#    StoreNginxSettings         Save parsed nginx settings to file\n#    TestValue                  Evaluate a value in a string or key\n#    ViewCategories             Show available category of tests\n#    ViewGroups                 Display test groups\n#    WaitForKeyPress            Wait for user to press a key to continue\n#\n#################################################################################\n\n\n    ################################################################################\n    # Name        : AddHP()\n    # Description : Add hardening points and count them\n    #\n    # Parameters  : $1 = points to add (0 or higher)\n    #               $2 = maximum points (at least value of $1 or higher)\n    # Returns     : <nothing>\n    # Usage       : AddHP 1 3\n    ################################################################################\n\n    AddHP() {\n        HPADD=$1; HPADDMAX=$2\n        HPPOINTS=$((HPPOINTS + HPADD))\n        HPTOTAL=$((HPTOTAL + HPADDMAX))\n        if [ ${HPADD} -eq ${HPADDMAX} ]; then\n            LogText \"Hardening: assigned maximum number of hardening points for this item (${HPADDMAX}). Currently having ${HPPOINTS} points (out of ${HPTOTAL})\"\n        else\n            LogText \"Hardening: assigned partial number of hardening points (${HPADD} of ${HPADDMAX}). Currently having ${HPPOINTS} points (out of ${HPTOTAL})\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : AddSetting()\n    # Description : Addition of a setting for display with 'lynis show settings'\n    #\n    # Parameters  : $1 = setting\n    #               $2 = value\n    #               $3 = description\n    # Returns     : <nothing>\n    # Usage       : AddSetting debug 1 'Debug mode'\n    ################################################################################\n\n    AddSetting() {\n        if [ $# -eq 3 ]; then\n            SETTING=\"$1\"\n            VALUE=\"$2\"\n            DESCRIPTION=\"$3\"\n            if [ -z \"${SETTINGS_FILE}\" ]; then\n                CreateTempFile\n                SETTINGS_FILE=\"${TEMP_FILE}\"\n            fi\n            FIND=$(grep -E \"^${SETTING};\" ${SETTINGS_FILE})\n            if [ -z \"${FIND}\" ]; then\n                echo \"${SETTING};${VALUE};${DESCRIPTION};\" >> ${SETTINGS_FILE}\n            else\n                Debug \"Setting '${SETTING}' was already configured, overwriting previous line '${FIND}' in ${SETTINGS_FILE} with value '${VALUE}'\"\n                # Delete line first, then add new value (inline search and replace is messy)\n                CreateTempFile\n                TEMP_SETTINGS_FILE=\"${TEMP_FILE}\"\n                cat ${SETTINGS_FILE} > ${TEMP_SETTINGS_FILE}\n                sed -e '/^'\"${SETTING}\"';/d' ${TEMP_SETTINGS_FILE} > ${SETTINGS_FILE}\n                rm \"${TEMP_SETTINGS_FILE}\"\n                echo \"${SETTING};${VALUE};${DESCRIPTION};\" >> ${SETTINGS_FILE}\n            fi\n        else\n            echo \"Error: incorrect call to AddSetting. Needs 3 arguments.\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : AddSystemGroup()\n    # Description : Adds a system to a group, which can be used for categorizing\n    #\n    # Parameters  : $1 = group name\n    # Returns     : <nothing>\n    # Usage       : AddSystemGroup \"test\"\n    ################################################################################\n\n    AddSystemGroup() {\n        Report \"system_group[]=$1\"\n    }\n\n\n    ################################################################################\n    # Name        : CheckFilePermissions()\n    # Description : Check file permissions\n    #\n    # Parameters  : Full path to file or directory\n    # Returns     : PERMS (FILE_NOT_FOUND | OK | BAD)\n    # Notes       : This function might be replaced in future\n    ################################################################################\n\n    CheckFilePermissions() {\n        CHECKFILE=\"$1\"\n        if [ ! -d ${CHECKFILE} -a ! -f ${CHECKFILE} ]; then\n            PERMS=\"FILE_NOT_FOUND\"\n            FILEVALUE=\"\"\n        else\n            # If 'file' is an directory, use -d\n            if [ -d ${CHECKFILE} ]; then\n                FILEVALUE=$(ls -d -l ${CHECKFILE} | cut -c 2-10)\n                PROFILEVALUE=$(grep '^permdir' ${PROFILE} | grep \"=${CHECKFILE}:\" | cut -d: -f2)\n            else\n                FILEVALUE=$(ls -l ${CHECKFILE} | cut -c 2-10)\n                PROFILEVALUE=$(grep '^permfile' ${PROFILE} | grep \"=${CHECKFILE}:\" | cut -d: -f2)\n            fi\n            if [ \"${FILEVALUE}\" = \"${PROFILEVALUE}\" ]; then PERMS=\"OK\"; else PERMS=\"BAD\"; fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : CheckItem()\n    # Description : Check if a specific item exists in the report\n    #\n    # Parameters  : $1 = key\n    #               $2 = value\n    # Returns     : exit code (0 = True, 1 = False)\n    # Usage       : if CheckItem \"key\" \"value\"; then ....; fi\n    ################################################################################\n\n    CheckItem() {\n        RETVAL=255\n        if [ $# -eq 2 ]; then\n            # Don't search in /dev/null, it's too empty there\n            if [ ! \"${REPORTFILE}\" = \"/dev/null\" ]; then\n                # Check if we can find the main type (with or without brackets)\n                LogText \"Test: search string $2 in earlier discovered results\"\n                FIND=$(grep -E \"^$1(\\[\\])?=\" ${REPORTFILE} | grep -E \"$2\")\n                if HasData \"${FIND}\"; then\n                    RETVAL=0\n                    LogText \"Result: found search string (result: $FIND)\"\n                else\n                    LogText \"Result: search string NOT found\"\n                    RETVAL=1\n                fi\n            else\n                LogText \"Skipping search, as /dev/null is being used\"\n            fi\n            return ${RETVAL}\n        else\n            ReportException ${TEST_NO} \"Error in function call to CheckItem\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : CheckUpdates()\n    # Description : Determine if there is an update available\n    #\n    # Returns     : <nothing>\n    # Usage       : CheckUpdates\n    #               Use PROGRAM_LV (latest version) and compare it with actual version (PROGRAM_AC)\n    ################################################################################\n\n    CheckUpdates() {\n        PROGRAM_LV=\"0000000000\"; DB_MALWARE_LV=\"0000000000\"; DB_FILEPERMS_LV=\"0000000000\"\n        if [ ${RUN_UPDATE_CHECK} -eq 1 ]; then\n            LYNIS_LV_RECORD=\"lynis-latest-version.cisofy.com.\"\n            FIND=$(which dig 2> /dev/null | grep -v \"no [^ ]* in\")\n            if [ -n \"${FIND}\" ]; then\n                PROGRAM_LV=$(dig +short +time=3 -t txt lynis-latest-version.cisofy.com 2> /dev/null | grep -v \"connection timed out\" | sed 's/[\".]//g' | grep \"^[1-9][0-9][0-9]$\")\n            else\n                FIND=$(which host 2> /dev/null | grep -v \"no [^ ]* in \")\n                if [ -n \"${FIND}\" ]; then\n                    PROGRAM_LV=$(host -t txt -W 3 lynis-latest-version.cisofy.com 2> /dev/null | grep -v \"connection timed out\" | awk '{ if ($1==\"lynis-latest-version.cisofy.com\" && $3==\"text\") { print $4 }}' | sed 's/\"//g' | grep \"^[1-9][0-9][0-9]$\")\n                    if [ \"${PROGRAM_LV}\" = \"\" ]; then PROGRAM_LV=0; fi\n                else\n                    FIND=$(which drill 2> /dev/null | grep -v \"no [^ ]* in \")\n                    if [ -n \"${FIND}\" ]; then\n                        PROGRAM_LV=$(drill txt ${LYNIS_LV_RECORD} | awk '{ if ($1==\"lynis-latest-version.cisofy.com.\" && $4==\"TXT\") { print $5 }}' | tr -d '\"' | grep \"^[1-9][0-9][0-9]$\")\n                        if [ -z \"${PROGRAM_LV}\" ]; then PROGRAM_LV=0; fi\n                    else\n                        LogText \"Result: dig, drill or host not installed, update check skipped\"\n                        UPDATE_CHECK_SKIPPED=1\n                    fi\n                fi\n            fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : CleanUp()\n    # Description : Delete PID and temporary files, stop execution (exit code 1)\n    #\n    # Parameters  : <none>\n    # Returns     : <nothing>\n    # Usage       : this function is triggered by a manual break by user\n    ################################################################################\n\n    CleanUp() {\n        echo \"\"; echo \"Interrupt detected.\"\n        RemovePIDFile\n        RemoveTempFiles\n        Display --text \"Cleaning up...\" --result DONE --color GREEN\n        ExitFatal\n    }\n\n\n    ################################################################################\n    # Name        : ContainsString()\n    # Description : Search a specific string (or regular expression) in another\n    #\n    # Returns     : exit code (0 = True, 1 = False)\n    # Usage       : if ContainsString \"needle\" \"there is a needle in the haystack\"; echo \"Found\"; else \"Not found\"; fi\n    ################################################################################\n\n    ContainsString() {\n        RETVAL=1\n        if [ $# -ne 2 ]; then ReportException \"ContainsString\" \"Incorrect number of arguments for ContainsStrings function\"; fi\n        FIND=$(echo \"$2\" | grep -E \"$1\")\n        if [ ! \"${FIND}\" = \"\" ]; then RETVAL=0; fi\n        return ${RETVAL}\n    }\n\n\n    ################################################################################\n    # Name        : CountTests()\n    # Description : Counter for the number of tests performed\n    #\n    # Parameters  : <none>\n    # Returns     : <nothing>\n    # Usage       : Call CountTests to increase number by 1\n    ################################################################################\n\n    CountTests() {\n        CTESTS_PERFORMED=$((CTESTS_PERFORMED + 1))\n    }\n\n\n    ################################################################################\n    # Name        : CreateTempFile()\n    # Description : Creates a temporary file\n    #\n    # Returns     : TEMP_FILE (variable)\n    # Usage       : CreateTempFile\n    #               if [ ! \"${TEMP_FILE}\" = \"\" ]; then\n    #                   MYTMPFILE=\"${TEMP_FILE}\"\n    #                   echo \"My temporary file is ${MYTMPFILE}\"\n    #               fi\n    ################################################################################\n\n    CreateTempFile() {\n        TEMP_FILE=\"\"\n        if [ \"${OS}\" = \"AIX\" ]; then\n            RANDOMSTRING1=\"lynis-$(od -N4 -tu /dev/random | awk 'NR==1 {print $2} {}')\"\n            TEMP_FILE=\"/tmp/${RANDOMSTRING1}\"\n            touch ${TEMP_FILE}\n        else\n            TEMP_FILE=$(mktemp /tmp/lynis.XXXXXXXXXX) || exit 1\n        fi\n        if [ ! \"${TEMP_FILE}\" = \"\" ]; then\n            LogText \"Action: created temporary file ${TEMP_FILE}\"\n        else\n            Fatal \"Could not create a temporary file\"\n        fi\n        # Add temporary file to queue for cleanup later\n        TEMP_FILES=\"${TEMP_FILES} ${TEMP_FILE}\"\n    }\n\n\n    ################################################################################\n    # Name        : DirectoryExists()\n    # Description : Check if a directory exists\n    #\n    # Returns     : exit code (0 = True, 1 = False)\n    # Usage       : if DirectoryExists; then echo \"it exists\"; else echo \"It does not exist\"; fi\n    ################################################################################\n\n    # Determine if a directory exists\n    DirectoryExists() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling DirectoryExists function\"; fi\n        DIRECTORY_FOUND=0\n        LogText \"Test: checking if directory $1 exists\"\n        if [ -d $1 ]; then\n            LogText \"Result: directory $1 exists\"\n            DIRECTORY_FOUND=1\n            return 0\n        else\n            LogText \"Result: directory $1 NOT found\"\n            return 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : Debug()\n    # Description : Show additional information on screen\n    #\n    # Input       : $1 = text\n    # Returns     : <nothing>\n    # Usage       : Debug \"More details\"\n    ################################################################################\n\n    Debug() {\n        if [ ${DEBUG} -eq 1 -a $# -gt 0 ]; then echo \"${PURPLE}[DEBUG]${NORMAL} $1\"; fi\n    }\n\n\n    ################################################################################\n    # Name        : DigitsOnly()\n    # Description : Only extract numbers from a string\n    #\n    # Returns     : Digits only string (VALUE)\n    ################################################################################\n\n    DigitsOnly() {\n        VALUE=$1\n        LogText \"Value is now: ${VALUE}\"\n        if [ ! \"${AWKBINARY}\" = \"\" ]; then\n            VALUE=$(echo ${VALUE} | grep -Eo '[0-9]{1,}')\n        fi\n        LogText \"Returning value: ${VALUE}\"\n    }\n\n\n    ################################################################################\n    # Name        : DiscoverProfiles()\n    # Description : Determine which profiles we have available\n    #\n    # Returns     : <nothing>\n    # Usage       : DiscoverProfiles\n    ################################################################################\n\n    DiscoverProfiles() {\n        # Try to find a default and custom profile, unless one was specified manually\n        if [ \"${PROFILE}\" = \"\" ]; then\n            CUSTOM_PROFILE=\"\"\n            DEFAULT_PROFILE=\"\"\n            PROFILEDIR=\"\"\n            tPROFILE_NAMES=\"default.prf custom.prf\"\n            if [ ${USE_CWD} -eq 1 ]; then\n                tPROFILE_TARGETS=\".\"\n            else\n                tPROFILE_TARGETS=\"/usr/local/etc/lynis /etc/lynis /usr/local/lynis .\"\n            fi\n            for PNAME in ${tPROFILE_NAMES}; do\n                for PLOC in ${tPROFILE_TARGETS}; do\n                    # Only use one default.prf\n                    if [ \"${PNAME}\" = \"default.prf\" -a ! \"${DEFAULT_PROFILE}\" = \"\" ]; then\n                        Debug \"Already discovered default.prf - skipping this file (${PLOC}/${PNAME})\"\n                    elif [ \"${PNAME}\" = \"custom.prf\" -a ! \"${CUSTOM_PROFILE}\" = \"\" ]; then\n                        Debug \"Already discovered custom.prf - skipping this file (${PLOC}/${PNAME})\"\n                    else\n                        if [ \"${PLOC}\" = \".\" ]; then FILE=\"${WORKDIR}/${PNAME}\"; else FILE=\"${PLOC}/${PNAME}\"; fi\n                        if [ -r ${FILE} ]; then\n                            PROFILES=\"${PROFILES} ${FILE}\"\n                            case ${PNAME} in\n                                \"custom.prf\") CUSTOM_PROFILE=\"${FILE}\" ;;\n                                \"default.prf\") DEFAULT_PROFILE=\"${FILE}\" ;;\n                            esac\n                            # Set profile directory to last match (Lynis could be both installed, and run as a separate download)\n                            if [ \"${PLOC}\" = \".\" ]; then PROFILEDIR=\"${WORKDIR}\"; else PROFILEDIR=\"${PLOC}\"; fi\n                        fi\n                    fi\n                done\n            done\n            # Search any profiles defined with --profile\n            for FILE in ${SEARCH_PROFILES}; do\n                if [ -r \"${FILE}\" ]; then\n                    Debug \"Found profile defined with --profile\"\n                    PROFILES=\"${PROFILES} ${FILE}\"\n                else\n                    ExitFatal \"Could not find or read profile (${FILE})\"\n                fi\n            done\n        fi\n        if [ \"${PROFILES}\" = \"\" ]; then\n            echo \"${RED}Fatal error: ${WHITE}No profile defined and could not find default profile${NORMAL}\"\n            echo \"Search paths used --> ${tPROFILE_TARGETS}\"\n            ExitCustom 66\n        else\n            PROFILES=$(echo ${PROFILES} | sed 's/^ //')\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : Display()\n    # Description : Show text on screen, with markup\n    #\n    # Input       : <multiple parameters, see test>\n    # Returns     : <nothing>\n    ################################################################################\n\n    Display() {\n        INDENT=0; TEXT=\"\"; RESULT=\"\"; COLOR=\"\"; SPACES=0; SHOWDEBUG=0\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --color)\n                    shift\n                        case $1 in\n                          GREEN)   COLOR=$GREEN   ;;\n                          RED)     COLOR=$RED     ;;\n                          WHITE)   COLOR=$WHITE   ;;\n                          YELLOW)  COLOR=$YELLOW  ;;\n                        esac\n                ;;\n                --debug)\n                    SHOWDEBUG=1\n                ;;\n                --indent)\n                    shift\n                    INDENT=$1\n                ;;\n                --result)\n                    shift\n                    RESULT=$1\n                ;;\n                --text)\n                    shift\n                    TEXT=$1\n                ;;\n                *)\n                    echo \"INVALID OPTION (Display): $1\"\n                    ExitFatal\n                ;;\n            esac\n            # Go to next parameter\n            shift\n        done\n\n        if [ -z \"${RESULT}\" ]; then\n            RESULTPART=\"\"\n        else\n            if [ ${CRONJOB} -eq 0 ]; then\n                RESULTPART=\" [ ${COLOR}${RESULT}${NORMAL} ]\"\n            else\n                RESULTPART=\" [ ${RESULT} ]\"\n            fi\n        fi\n\n        if [ -n \"${TEXT}\" ]; then\n            SHOW=0\n            if [ ${SHOW_WARNINGS_ONLY} -eq 1 ]; then\n                if [ \"${RESULT}\" = \"WARNING\" ]; then SHOW=1; fi\n            elif [ ${QUIET} -eq 0 ]; then SHOW=1\n            fi\n\n            if [ ${SHOW} -eq 1 ]; then\n                # Display:\n                # - for full shells, count with -m instead of -c, to support language locale (older busybox does not have -m)\n                # - wc needs LANG to deal with multi-bytes characters but LANG has been unset in include/consts\n                LINESIZE=$(export LC_ALL= ; export LANG=\"${DISPLAY_LANG}\";echo \"${TEXT}\" | wc -m | tr -d ' ')\n                if [ ${SHOWDEBUG} -eq 1 ]; then DEBUGTEXT=\" [${PURPLE}DEBUG${NORMAL}]\"; else DEBUGTEXT=\"\"; fi\n                if [ ${INDENT} -gt 0 ]; then SPACES=$((62 - INDENT - LINESIZE)); fi\n                if [ ${SPACES} -lt 0 ]; then SPACES=0; fi\n                if [ ${CRONJOB} -eq 0 ]; then\n                    # Check if we already have already discovered a proper echo command tool. It not, set it default to 'echo'.\n                    if [ \"${ECHOCMD}\" = \"\" ]; then ECHOCMD=\"echo\"; fi\n                    ${ECHOCMD} \"\\033[${INDENT}C${TEXT}\\033[${SPACES}C${RESULTPART}${DEBUGTEXT}\"\n                else\n                    echo \"${TEXT}${RESULTPART}\"\n                fi\n            fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : DisplayError()\n    # Description : Show error on screen\n    #\n    # Input       : $1 = text (string), $2 = optional exit code (integer)\n    # Returns     : <nothing>\n    ################################################################################\n\n    DisplayError() {\n        EXITCODE=\"\"\n        if [ $# -gt 1 ]; then EXITCODE=$2; fi\n        ${ECHOCMD} \"\"\n        ${ECHOCMD} \"${WARNING}Error${NORMAL}: ${BOLD}$1${NORMAL}\"\n        ${ECHOCMD} \"\"\n        if [ -n \"${EXITCODE}\" ]; then ExitCustom ${EXITCODE}; fi\n    }\n\n\n    ################################################################################\n    # Name        : DisplayException()\n    # Description : Show a discovered exception on screen\n    #\n    # Parameters  : $1 = function or test\n    #               $2 = text\n    # Returns     : <nothing>\n    # Note        : This function is usually triggered by ReportException\n    ################################################################################\n\n    DisplayException() {\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"=================================================================\"\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"  ${WARNING}Exception found!${NORMAL}\"\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"  Function/test:  [$1]\"\n        ${ECHOCMD:-echo} \"  Message:        ${BOLD}$2${NORMAL}\"\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"  Help improving the Lynis community with your feedback!\"\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"  Steps:\"\n        ${ECHOCMD:-echo} \"  - Ensure you are running the latest version ($0 update check)\"\n        ${ECHOCMD:-echo} \"  - If so, create a GitHub issue at ${PROGRAM_SOURCE}\"\n        ${ECHOCMD:-echo} \"  - Include relevant parts of the log file or configuration file\"\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"  Thanks!\"\n        ${ECHOCMD:-echo} \"\"\n        ${ECHOCMD:-echo} \"=================================================================\"\n        ${ECHOCMD:-echo} \"\"\n        sleep 5\n    }\n\n\n    ################################################################################\n    # Name        : DisplayManual()\n    # Description : Show text on screen, without any markup\n    #\n    # Input       : $1 = text (string)\n    # Returns     : <nothing>\n    ################################################################################\n\n    DisplayManual() {\n        if [ ${QUIET} -eq 0 ]; then ${ECHOCMD} \"$1\"; fi\n    }\n\n\n    ################################################################################\n    # Name        : DisplayToolTip()\n    # Description : Show tooltip on screen\n    #\n    # Input       : $1 = text\n    # Returns     : <nothing>\n    ################################################################################\n\n    DisplayToolTip() {\n        # Display tooltip when enabled and no tip has been displayed yet\n        if [ ${SHOW_TOOL_TIPS} -eq 1 -a ${TOOLTIP_SHOWED} -eq 0 -a ${QUIET} -eq 0 ]; then\n            # Check if we already have already discovered a proper echo command tool. It not, set it default to 'echo'.\n            if [ \"${ECHOCMD}\" = \"\" ]; then ECHOCMD=\"echo\"; fi\n            if [ ${CRONJOB} -eq 0 ]; then\n                printf \"\\n\"\n                ${ECHOCMD} \"  ${BG_BLUE}[TIP]${NORMAL}: ${LIGHTBLUE}$1${NORMAL}\"\n                printf \"\\n\"\n            else\n                ${ECHOCMD} \"  [TIP]: $1\"\n            fi\n            TOOLTIP_SHOWED=1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : DisplayWarning\n    # Description : Show a warning on the screen\n    #\n    # Parameters  : $1 = text\n    # Returns     : <nothing>\n    ################################################################################\n\n    DisplayWarning() {\n        if [ ${CRONJOB} -eq 0 ]; then\n            printf \"\\n\"\n            ${ECHOCMD:-echo} \"  ${BG_WARNING}[WARNING]${NORMAL}: $1${NORMAL}\"\n            printf \"\\n\"\n        else\n            ${ECHOCMD} \"  [WARNING]: $1\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : Equals()\n    # Description : Compare two strings after special characters were stripped\n    #\n    # Parameters  : $1 = string1\n    #               $2 = string2\n    # Returns     : exit code (0 = True, 1 = False)\n    # Usage       : if Equals \"${MYDIR}\" \"/etc\"; then echo \"Found\"; else \"Not found\"; fi\n    ################################################################################\n\n    Equals() {\n        RETVAL=1\n        if [ $# -ne 2 ]; then ReportException \"Equals\" \"Incorrect number of arguments for $0 function\"; fi\n\n        # Strip any strange control characters\n        INPUT1=$(echo $1 | tr -d '[:cntrl:]<>' | ${SEDBINARY} 's/__space__/ /g' | ${SEDBINARY} 's/:space:/ /g')\n        INPUT2=$(echo $2 | tr -d '[:cntrl:]<>' | ${SEDBINARY} 's/__space__/ /g' | ${SEDBINARY} 's/:space:/ /g')\n        if [ \"${INPUT1}\" = \"${INPUT2}\" ]; then RETVAL=0; fi\n\n        return ${RETVAL}\n    }\n\n\n    ################################################################################\n    # Name        : ExitClean()\n    # Description : Perform a normal exit of the program, and clean up resources\n    #\n    # Parameters  : <nothing>\n    # Returns     : <nothing>\n    # Usage       : ExitClean\n    ################################################################################\n\n    ExitClean() {\n        RemovePIDFile\n        RemoveTempFiles\n        LogText \"${PROGRAM_NAME} ended successfully.\"\n        exit 0\n    }\n\n\n    ################################################################################\n    # Name        : ExitCustom()\n    # Description : Perform a normal exit of the program, and clean up resources\n    #\n    # Parameters  : $1 = exit code (optional)\n    # Returns     : <nothing>\n    # Usage       : ExitCustom 35\n    ################################################################################\n\n    ExitCustom() {\n        RemovePIDFile\n        RemoveTempFiles\n        # Exit with the exit code given, otherwise use 1\n        if [ $# -eq 1 ]; then\n            LogText \"${PROGRAM_NAME} ended with exit code $1.\"\n            exit $1\n        else\n            LogText \"${PROGRAM_NAME} ended with exit code 1.\"\n            exit 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : ExitFatal()\n    # Description : Perform exit of the program (with code 1), clean up resources\n    #\n    # Parameters  : $1 = text string (optional)\n    # Returns     : <nothing>\n    # Usage       : ExitFatal\n    ################################################################################\n\n    ExitFatal() {\n        RemovePIDFile\n        RemoveTempFiles\n        LogText \"${PROGRAM_NAME} ended with exit code 1.\"\n        if [ $# -eq 1 ]; then\n            ${ECHOCMD:-echo} \"\"\n            ${ECHOCMD:-echo} \"${RED}Fatal error${NORMAL}: ${WHITE}$1${NORMAL}\"\n            ${ECHOCMD:-echo} \"\"\n        fi\n        exit 1\n    }\n\n\n    ################################################################################\n    # Name        : FileExists()\n    # Description : Determine if a file exists\n    #\n    # Parameters  : $1 = path\n    # Returns     : 0 (found), 1 (not found)\n    #               FILE_FOUND (0:found, 1:not found) - deprecated usage\n    ################################################################################\n\n    FileExists() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling FileExists function\"; fi\n        FILE_FOUND=0\n        LogText \"Test: checking if file $1 exists\"\n        if [ -f $1 ]; then\n            LogText \"Result: file $1 exists\"\n            FILE_FOUND=1\n            return 0\n        else\n            LogText \"Result: file $1 NOT found\"\n            return 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : FileInstalledByPackage()\n    # Description : Check if a file is part of a package\n    # Returns     : 0 (true), 1 (default: unknown or false)\n    ################################################################################\n\n    FileInstalledByPackage() {\n        exitcode=1\n        file=$1\n        find=\"\"\n        if [ -n \"${DPKGBINARY}\" ]; then\n            find=$(${DPKGBINARY} -S \"${file}\" 2> /dev/null | ${AWKBINARY} -F: '{print $1}')\n        elif [ -n \"${RPMBINARY}\" ]; then\n            find=$(${RPMBINARY} -qf \"${file}\" 2> /dev/null | ${AWKBINARY} -F- '{print $1}')\n        fi\n        if [ -n \"${find}\" ]; then\n            LogText \"Result: file '${file}' belongs to package (${find})\"\n            exitcode=0\n        else\n            LogText \"Result: file '${file}' does most likely not belong to a package\"\n        fi\n        return ${exitcode}\n    }\n\n\n    ################################################################################\n    # Name        : FileIsEmpty()\n    # Description : Check if a file is empty\n    #\n    # Returns     : 0 (empty), 1 (not empty)\n    #               EMPTY (0 or 1) - deprecated usage\n    # Usage       : if FileIsEmpty /etc/passwd; then\n    ################################################################################\n\n    FileIsEmpty() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling FileIsEmpty function\"; fi\n        EMPTY=0\n        LogText \"Test: checking if file $1 is empty\"\n        if [ ! -s \"$1\" ]; then\n            LogText \"Result: file $1 is empty\"\n            EMPTY=1\n            return 0\n        else\n            LogText \"Result: file $1 is NOT empty\"\n            return 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : FileIsReadable()\n    # Description : Check if a file readable or directory is accessible\n    #\n    # Returns     : Return code (0 = readable, 1 = not readable)\n    # Usage       : if FileIsReadable /etc/shadow; then echo \"File is readable\"; fi\n    ################################################################################\n\n    FileIsReadable() {\n        if [ $# -eq 0 ]; then ExitFatal \"Function FileIsReadable() called without a file name\"; fi\n        sFILE=$1\n        CANREAD=0\n        RETVAL=1\n        escaped_file=$(echo ${sFILE} | sed 's/\\*/\\\\*/; s/?/\\\\?/')\n        LogText \"Test: check if we can access ${sFILE} (escaped: ${escaped_file})\"\n\n        # Check for symlink\n        if [ -L \"${escaped_file}\" ]; then\n            ShowSymlinkPath ${escaped_file}\n            if [ -n \"${SYMLINK}\" ]; then escaped_file=\"${SYMLINK}\"; fi\n        fi\n\n        # Only check the file if it isn't a symlink (after previous check)\n        if [ -L \"${escaped_file}\" ]; then\n            OTHERPERMS=\"-\"\n            LogText \"Result: unclear if we can read this file, as this is a symlink\"\n            ReportException \"FileIsReadable\" \"Can not determine symlink ${sFILE}\"\n        elif [ -d \"${escaped_file}\" ]; then\n            OTHERPERMS=$(${LSBINARY} -d -l \"${escaped_file}\" 2> /dev/null | ${CUTBINARY} -c 8)\n        elif [ -f \"${escaped_file}\" ]; then\n            OTHERPERMS=$(${LSBINARY} -d -l \"${escaped_file}\" 2> /dev/null | ${CUTBINARY} -c 8)\n        else\n            OTHERPERMS=\"-\"\n        fi\n\n        # Also check if we are the actual owner of the file (use -d to get directory itself, if its a directory)\n        FILEOWNER=$(ls -dln \"${escaped_file}\" 2> /dev/null | ${AWKBINARY} -F\" \" '{ print $3 }')\n        if [ \"${FILEOWNER}\" = \"${MYID}\" ]; then\n            LogText \"Result: file is owned by our current user ID (${MYID}), checking if it is readable\"\n            if [ -L \"${sFILE}\" ]; then\n                LogText \"Result: unclear if we can read this file, as this is a symlink\"\n                ReportException \"FileIsReadable\" \"Can not determine symlink ${escaped_file}\"\n            elif [ -d \"${escaped_file}\" ]; then\n                OTHERPERMS=$(${LSBINARY} -d -l \"${escaped_file}\" 2> /dev/null | ${CUTBINARY} -c 2)\n            elif [ -f \"${escaped_file}\" ]; then\n                OTHERPERMS=$(${LSBINARY} -l \"${escaped_file}\" 2> /dev/null | ${CUTBINARY} -c 2)\n            fi\n        else\n            LogText \"Result: file is not owned by current user ID (${MYID}), but UID ${FILEOWNER}\"\n        fi\n\n        # Check if we are root, or have the read bit\n        if [ \"${MYID}\" = \"0\" -o \"${OTHERPERMS}\" = \"r\" ]; then\n            CANREAD=1\n            LogText \"Result: file ${escaped_file} is readable (or directory accessible).\"\n            return 0\n        else\n            return 1\n            LogText \"Result: file ${escaped_file} is NOT readable (or directory accessible), symlink, or does not exist. (OTHERPERMS: ${OTHERPERMS})\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : GetHostID()\n    # Description : Create an unique id for the system\n    #\n    # Returns     : 0 = fetched or created IDs, 1 = failed, 2 = skipped\n    # Usage       : GetHostID\n    ################################################################################\n\n    GetHostID() {\n        if [ ${SKIP_GETHOSTID} -eq 1 ]; then\n            Debug \"Skipping HostID generation due to SKIP_GETHOSTID\"\n            return 2\n        fi\n\n        if [ -n \"${HOSTID}\" -a -n \"${HOSTID2}\" ]; then\n            Debug \"Skipping creation of host identifiers, as they are already configured (via profile)\"\n            HOSTID_GEN=\"profile\"\n            return 2\n        fi\n\n        if [ -f \"${ROOTDIR}etc/lynis/hostids\" ]; then\n            HOSTID=$(grep \"^hostid=\" ${ROOTDIR}etc/lynis/hostids | awk -F= '{print $2}')\n            HOSTID2=$(grep \"^hostid2=\" ${ROOTDIR}etc/lynis/hostids | awk -F= '{print $2}')\n            Debug \"Used hostids file to fetch values\"\n            HOSTID_GEN=\"hostids-file\"\n            return 0\n        fi\n\n        FIND=\"\"\n        # Avoid some hashes (empty, only zeros)\n        BLACKLISTED_HASHES=\"6ef1338f520d075957424741d7ed35ab5966ae97 adc83b19e793491b1c6ea0fd8b46cd9f32e592fc\"\n        # Check which utilities we can use (e.g. lynis show hostids). Normally these are detected during binaries collecting.\n        if [ \"${SHA1SUMBINARY}\" = \"\" ]; then SHA1SUMBINARY=$(which sha1sum 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${SHA1SUMBINARY}\" = \"\" ]; then SHA1SUMBINARY=$(which sha1 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${SHA256SUMBINARY}\" = \"\" ]; then SHA256SUMBINARY=$(which sha256sum 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${SHA256SUMBINARY}\" = \"\" ]; then SHA256SUMBINARY=$(which sha256 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${CSUMBINARY}\" = \"\" ]; then CSUMBINARY=$(which csum 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${OPENSSLBINARY}\" = \"\" ]; then OPENSSLBINARY=$(which openssl 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${IFCONFIGBINARY}\" = \"\" ]; then IFCONFIGBINARY=$(which ifconfig 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n        if [ \"${IPBINARY}\" = \"\" ]; then IPBINARY=$(which ip 2> /dev/null | grep -v \"no [^ ]* in \"); fi\n\n        # If using openssl, use the best hash type it supports\n        if [ ! \"${OPENSSLBINARY}\" = \"\" ]; then\n            OPENSSL_HASHLIST=$(openssl dgst -h 2>&1)\n            for OPENSSL_HASHTYPE in sha256 sha1 md5 ; do\n                if echo \"${OPENSSL_HASHLIST}\" | grep \"^-${OPENSSL_HASHTYPE} \" >/dev/null ; then\n                    break\n                fi\n            done\n        fi\n\n        if [ ! \"${SHA1SUMBINARY}\" = \"\" -o ! \"${SHA256SUMBINARY}\" = \"\" -o ! \"${OPENSSLBINARY}\" = \"\" -o ! \"${CSUMBINARY}\" = \"\" ]; then\n            LogText \"Info: found hashing tool, start generation of HostID\"\n            case \"${OS}\" in\n\n                \"AIX\")\n                    # Common interfaces: en0 en1 en2, ent0 ent1 ent2\n                    FIND=$(entstat en0 2>/dev/null | grep \"Hardware Address\" | awk -F \": \" '{ print $2 }')\n                    if [ \"${FIND}\" = \"\" ]; then\n                        FIND=$(entstat ent0 2>/dev/null | grep \"Hardware Address\" | awk -F \": \" '{ print $2 }')\n                    fi\n                    if [ ! \"${FIND}\" = \"\" ]; then\n                        # We have a MAC address, now hashing it\n                        if [ -n \"${SHA1SUMBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${SHA1SUMBINARY} | awk '{ print $1 }')\n                        elif [ -n \"${CSUMBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${CSUMBINARY} -h SHA1 - | awk '{ print $1 }')\n                        elif [ -n \"${OPENSSLBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${OPENSSLBINARY} sha -sha1 | awk '{ print $2 }')\n                        else\n                            ReportException \"GetHostID\" \"No sha1, sha1sum, csum or openssl binary available on AIX\"\n                        fi\n                    else\n                        ReportException \"GetHostID\" \"No output from entstat on interfaces: en0, ent0\"\n                    fi\n                ;;\n\n                \"DragonFly\" | \"FreeBSD\")\n                    FIND=$(${IFCONFIGBINARY} | grep ether | head -n 1 | awk '{ print $2 }' | tr '[:upper:]' '[:lower:]')\n                    if HasData \"${FIND}\"; then\n                        HOSTID=$(echo ${FIND} | sha1)\n                    else\n                        ReportException \"GetHostID\" \"No MAC address returned on DragonFly or FreeBSD\"\n                    fi\n                ;;\n\n                \"HP-UX\")\n                    FIND=$(nwmgr -q info -c lan0 2> /dev/null | awk '{ if ($1==\"MAC\" && $2==\"Address\") { print $4 }}')\n                    if HasData \"${FIND}\"; then\n                        if [ -n \"${OPENSSLBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${OPENSSLBINARY} sha -sha1 | awk '{ print $2 }')\n                        else\n                            ReportException \"GetHostID\" \"No openssl binary available on this HP-UX system\"\n                        fi\n                    else\n                        ReportException \"GetHostID\" \"No MAC address found by using nwmgr\"\n                    fi\n                ;;\n\n                \"Linux\")\n                    # Try fetching information from /sys in case 'ip' is not available or does not give expected results\n                    if IsEmpty \"${FIND}\" && [ -d /sys/class/net ]; then\n                        NET_INTERFACES=$(${FINDBINARY} /sys/class/net ! -type d -exec realpath {} \\; 2> /dev/null | sort | awk -F'/' '!/virtual/ && /devices/ {for (x=1;x<=NF;x++) if ($x~\"net\") print $(x+1)}')\n                        for INTERFACE in ${NET_INTERFACES}; do\n                            if grep -q -s 'up' \"/sys/class/net/${INTERFACE}/operstate\"; then\n                                LogText \"Interface '${INTERFACE}' is up, fetching MAC address\"\n                                FIND=$(head -n 1 \"/sys/class/net/${INTERFACE}/address\" | tr '[:upper:]' '[:lower:]')\n                                if HasData \"${FIND}\"; then\n                                    HOSTID_GEN=\"linux-sys-interface-up\"\n                                    break\n                                fi\n                            fi\n                        done\n                    fi\n\n                    # Next is to try ip, as it is available to most modern Linux distributions\n                    if IsEmpty \"${FIND}\" && [ -n \"${IPBINARY}\" ]; then\n                        LogText \"Info: trying output from 'ip' to generate HostID\"\n                        # Determine if we have the common available eth0 interface. If so, give that priority.\n                        # Note: apply sorting in case there would be multiple MAC addresses linked to increase predictable end result\n                        FIND=$(${IPBINARY} addr show eth0 2> /dev/null | grep -E \"link/ether \" | awk '{ print $2 }' | tr '[:upper:]' '[:lower:]' | sort | head -n 1)\n                        if HasData \"${FIND}\"; then\n                            HOSTID_GEN=\"linux-ip-interface-eth0\"\n                        else\n                            # If eth0 does not exist, which is also common, then trying the next option:\n                            # 1) First fetch all links that are UP\n                            # 2) Filter entries that have a MAC address and filter out Docker related MAC addresses starting with '02:42:'\n                            # 3) Convert everything to lowercase\n                            # 4) Sort the entries, so that the output is more predictable between runs when the same interfaces are available\n                            # 5) Select first entry\n                            FIND=$(${IPBINARY} -family link addr show up 2> /dev/null | awk '{if($1==\"link/ether\" && $2 !~ \"^02:42:\"){print $2}}' | tr '[:upper:]' '[:lower:]' | sort | head -n 1)\n                            if HasData \"${FIND}\"; then\n                                HOSTID_GEN=\"linux-ip-interface-up-other\"\n                            else\n                                ReportException \"GetHostID\" \"Can't create hostid (no MAC addresses found)\"\n                            fi\n                        fi\n                    fi\n\n                    # Finally try ifconfig\n                    if IsEmpty \"${FIND}\" && [ -n \"${IFCONFIGBINARY}\" ]; then\n                        LogText \"Info: no information found from 'ip' or in /sys, trying output from 'ifconfig'\"\n                        # Determine if we have the eth0 interface (not all Linux distributions have this, e.g. Arch)\n                        HASETH0=$(${IFCONFIGBINARY} | grep \"^eth0\")\n                        # Check if we can find it with HWaddr on the line\n                        FIND=$(${IFCONFIGBINARY} 2> /dev/null | grep \"^eth0\" | grep -v \"eth0:\" | grep HWaddr | awk '{ print $5 }' | tr '[:upper:]' '[:lower:]')\n\n                        # If nothing found, then try first for alternative interface. Else other versions of ifconfig (e.g. Slackware/Arch)\n                        if IsEmpty \"${FIND}\"; then\n                            FIND=$(${IFCONFIGBINARY} 2> /dev/null | grep HWaddr)\n                            if IsEmpty \"${FIND}\"; then\n                                # If possible directly address eth0 to avoid risking gathering the incorrect MAC address.\n                                # If not, then falling back to getting first interface. Better than nothing.\n                                if HasData \"${HASETH0}\"; then\n                                    FIND=$(${IFCONFIGBINARY} eth0 2> /dev/null | grep \"ether \" | awk '{ print $2 }' | tr '[:upper:]' '[:lower:]')\n                                    if HasData \"${FIND}\"; then\n                                        HOSTID_GEN=\"linux-ifconfig-interface-eth0-ether\"\n                                    fi\n                                else\n                                    FIND=$(${IFCONFIGBINARY} 2> /dev/null | grep \"ether \" | awk '{ print $2 }' | head -n 1 | tr '[:upper:]' '[:lower:]')\n                                    if IsEmpty \"${FIND}\"; then\n                                        ReportException \"GetHostID\" \"No eth0 found (and no ether was found with ifconfig)\"\n                                    else\n                                        HOSTID_GEN=\"linux-ifconfig-interface-first-ether\"\n                                        LogText \"Result: No eth0 found (but ether found), using first network interface to determine hostid (with ifconfig)\"\n                                    fi\n                                fi\n                            else\n                                FIND=$(${IFCONFIGBINARY} 2> /dev/null | grep HWaddr | head -n 1 | awk '{ print $5 }' | tr '[:upper:]' '[:lower:]')\n                                HOSTID_GEN=\"linux-ifconfig-interface-first-hwaddr\"\n                            fi\n                        else\n                            HOSTID_GEN=\"linux-ifconfig-interface-eth0-hwaddr\"\n                        fi\n                    fi\n\n                    # Check if we found a MAC address to generate the HostID\n                    if HasData \"${FIND}\"; then\n                        LogText \"Info: using hardware address '${FIND}' to create HostID\"\n                        if [ -n \"${SHA1SUMBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${SHA1SUMBINARY} | awk '{ print $1 }')\n                        elif [ -n \"${SHA256SUMBINARY}\" ]; then\n                            # Truncate hash to match SHA1 length\n                            HOSTID=$(echo ${FIND} | ${SHA256SUMBINARY} | awk '{ print $1 }' | head -c 40)\n                        fi\n                        LogText \"Result: Found HostID: ${HOSTID}\"\n                    else\n                        ReportException \"GetHostID\" \"HostID could not be generated\"\n                    fi\n                ;;\n\n                \"macOS\")\n                    FIND=$(${IFCONFIGBINARY} en0 | grep ether | head -n 1 | awk '{ print $2 }' | tr '[:upper:]' '[:lower:]')\n                    if [ ! \"${FIND}\" = \"\" ]; then\n                        HOSTID=$(echo ${FIND} | shasum | awk '{ print $1 }')\n                    else\n                        ReportException \"GetHostID\" \"No MAC address returned on macOS\"\n                    fi\n                    LYNIS_HOSTID2_PART1=$(hostname -s)\n                    if [ -n \"${LYNIS_HOSTID2_PART1}\" ]; then\n                        LogText \"Info: using hostname ${LYNIS_HOSTID2_PART1}\"\n                        LYNIS_HOSTID2_PART2=$(sysctl -n kern.uuid 2> /dev/null)\n                        if [ -n \"${LYNIS_HOSTID2_PART2}\" ]; then\n                            LogText \"Info: using UUID ${LYNIS_HOSTID2_PART2}\"\n                        else\n                            LogText \"Info: could not create HOSTID2 as kern.uuid sysctl key is missing\"\n                        fi\n                        HOSTID2=$(echo \"${LYNIS_HOSTID2_PART1}${LYNIS_HOSTID2_PART2}\" | shasum -a 256 | awk '{ print $1 }')\n                    else\n                        LogText \"Info: could not create HOSTID2 as hostname is missing\"\n                    fi\n                ;;\n\n                \"NetBSD\")\n                    FIND=$(${IFCONFIGBINARY} -a | grep \"address:\" | head -n 1 | awk '{ print $2 }' | tr '[:upper:]' '[:lower:]')\n                    if HasData \"${FIND}\"; then\n                        HOSTID=$(echo ${FIND} | sha1)\n                    else\n                        ReportException \"GetHostID\" \"No MAC address returned on NetBSD\"\n                    fi\n                ;;\n\n                \"OpenBSD\")\n                    FIND=$(${IFCONFIGBINARY} | grep \"lladdr \" | head -n 1 | awk '{ print $2 }' | tr '[:upper:]' '[:lower:]')\n                    if HasData \"${FIND}\"; then\n                        HOSTID=$(echo ${FIND} | sha1)\n                    else\n                        ReportException \"GetHostID\" \"No MAC address returned on OpenBSD\"\n                    fi\n                ;;\n\n                \"Solaris\")\n                    INTERFACES_TO_TEST=\"net0 e1000g1 e1000g0\"\n                    FOUND=0\n                    for I in ${INTERFACES_TO_TEST}; do\n                         FIND=$(${IFCONFIGBINARY} -a | grep \"^${I}\")\n                         if [ ! \"${FIND}\" = \"\" ]; then\n                             FOUND=1; LogText \"Found interface ${I} on Solaris\"\n                             break\n                         fi\n                    done\n                    if [ ${FOUND} -eq 1 ]; then\n                        FIND=$(${IFCONFIGBINARY} ${I} | grep ether | awk '{ if ($1==\"ether\") { print $2 }}')\n                        if [ -n \"${SHA1SUMBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${SHA1SUMBINARY} | awk '{ print $1 }')\n                        elif [ -n \"${OPENSSLBINARY}\" ]; then\n                            HOSTID=$(echo ${FIND} | ${OPENSSLBINARY} sha -sha1 | awk '{ print $2 }')\n                        else\n                            ReportException \"GetHostID\" \"Can not find sha1/sha1sum or openssl\"\n                        fi\n                    else\n                        ReportException \"GetHostID\" \"No interface found on Solaris to create HostID\"\n                    fi\n                ;;\n\n                *)\n                        ReportException \"GetHostID\" \"Can't create HOSTID as OS is not supported yet by this function\"\n                ;;\n            esac\n\n            # Remove HOSTID if it contains a default MAC address with a related hash value\n            if [ -n \"${HOSTID}\" ]; then\n                for CHECKHASH in ${BLACKLISTED_HASHES}; do\n                    if [ \"${CHECKHASH}\" = \"${HOSTID}\" ]; then\n                        LogText \"Result: hostid is a blacklisted value\"\n                        HOSTID=\"\"\n                    fi\n                done\n            fi\n\n        else\n            ReportException \"GetHostID\" \"Can't create HOSTID as there is no hash tool available (sha1, sha1sum, openssl, truncated sha256sum)\"\n        fi\n\n        # Search machine ID\n        # This applies to IDs generated for systemd\n        # Optional: DBUS creates ID as well with dbus-uuidgen and is stored in /var/lib/dbus-machine-id (might be symlinked to /etc/machine-id)\n        sMACHINEIDFILE=\"/etc/machine-id\"\n        if [ -f ${sMACHINEIDFILE} ]; then\n            FIND=$(head -n 1 ${sMACHINEIDFILE} | grep \"^[a-f0-9]\")\n            if [ \"${FIND}\" = \"\" ]; then\n                MACHINEID=\"${FIND}\"\n            fi\n        fi\n\n        if [ -z \"${HOSTID}\" ]; then\n            LogText \"Result: no HOSTID available, trying to use SSH key as unique source\"\n            # Create host ID when a MAC address was not found\n            SSH_KEY_FILES=\"ssh_host_ed25519_key.pub ssh_host_ecdsa_key.pub ssh_host_dsa_key.pub ssh_host_rsa_key.pub\"\n            if [ -d /etc/ssh ]; then\n                for I in ${SSH_KEY_FILES}; do\n                    if [ -z \"${HOSTID}\" ]; then\n                        if [ -f /etc/ssh/${I} ]; then\n                            LogText \"Result: found ${I} in /etc/ssh\"\n                            if [ -n \"${SHA1SUMBINARY}\" ]; then\n                                HOSTID=$(${SHA1SUMBINARY} /etc/ssh/${I} | awk '{ print $1 }')\n                                LogText \"result: Created HostID with SSH key ($I): ${HOSTID}\"\n                                HOSTID_GEN=\"fallback-ssh-public-key\"\n                            else\n                                ReportException \"GetHostID\" \"Can't create HOSTID with SSH key, as sha1sum binary is missing\"\n                            fi\n                        fi\n                    fi\n                done\n            else\n                LogText \"Result: no /etc/ssh directory found, skipping\"\n            fi\n        fi\n\n        # Generation of HostID version 2\n        if [ -z \"${HOSTID2}\" ]; then\n            LogText \"Info: start generation of HostID (version 2)\"\n            FOUND=0\n            DATA_SSH=\"\"\n            if [ -d /etc/ssh ]; then\n                SSH_PUBKEY_FILES=\"ssh_host_ed25519_key.pub ssh_host_ecdsa_key.pub ssh_host_dsa_key.pub ssh_host_rsa_key.pub\"\n                for I in ${SSH_PUBKEY_FILES}; do\n                    if [ ${FOUND} -eq 0 ]; then\n                        if [ -f /etc/ssh/${I} ]; then\n                            LogText \"Result: found file ${I} in /etc/ssh, using that as candidate to create hostid2\"\n                            DATA_SSH=$(cat /etc/ssh/${I})\n                            FOUND=1\n                        fi\n                    fi\n                done\n            elif [ -d /etc/dropbear ]; then\n                SSH_KEY_FILES=\"dropbear_ed25519_host_key dropbear_rsa_host_key\"\n                for I in ${SSH_KEY_FILES}; do\n                    if [ ${FOUND} -eq 0 ]; then\n                        if [ -f \"/etc/dropbear/${I}\" ]; then\n                            LogText \"Result: found file ${I} in /etc/dropbear, using that as candidate to create hostid2\"\n                            # Dropbear stores both keys in one binary file\n                            DATA_SSH=$(dropbearkey -y -f \"/etc/dropbear/${I}\" | grep '^ssh')\n                            FOUND=1\n                        fi\n                    fi\n                done\n            else\n                LogText \"Result: no /etc/ssh nor /etc/dropbear directory found, skipping\"\n            fi\n\n            STRING_TO_HASH=\"\"\n            if [ ${FOUND} -eq 1 -a -n \"${DATA_SSH}\" ]; then\n                LogText \"Using SSH public key to create hostid2\"\n                STRING_TO_HASH=\"${DATA_SSH}\"\n                HOSTID2_GEN=\"ssh-public-key\"\n            else\n                if [ -n \"${MACHINEID}\" ]; then\n                    LogText \"Using the machine ID to create hostid2\"\n                    STRING_TO_HASH=\"${MACHINEID}\"\n                    HOSTID2_GEN=\"machine-id\"\n                fi\n            fi\n            # Check if we have a string to turn into a host identifier\n            if [ -n \"${STRING_TO_HASH}\" ]; then\n                # Create hashes\n                if [ -n \"${SHA256SUMBINARY}\" ]; then\n                    HASH2=$(echo ${STRING_TO_HASH} | ${SHA256SUMBINARY} | awk '{ print $1 }')\n                    HASH_HOSTNAME=$(echo ${HOSTNAME} | ${SHA256SUMBINARY} | awk '{ print $1 }')\n                elif [ -n \"${OPENSSLBINARY}\" ]; then\n                    HASH2=$(echo ${STRING_TO_HASH} | ${OPENSSLBINARY} dgst -${OPENSSL_HASHTYPE} | awk '{ print $2 }')\n                    HASH_HOSTNAME=$(echo ${HOSTNAME} | ${OPENSSLBINARY} dgst -${OPENSSL_HASHTYPE} | awk '{ print $2 }')\n                fi\n                LogText \"Hash (hostname): ${HASH_HOSTNAME}\"\n                LogText \"Hash (ssh or machineid): ${HASH2}\"\n                HOSTID2=\"${HASH2}\"\n            fi\n        fi\n\n        # Show an exception if no HostID could be created, to ensure each system (and scan) has one\n        if [ -z \"${HOSTID}\" ]; then\n            ReportException \"GetHostID\" \"No unique host identifier could be created.\"\n            return 1\n        elif [ -n \"${HOSTID2}\" ]; then\n            return 0\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : GetReportData()\n    # Description : Request data from report\n    # Returns     : Data (when matches were found)\n    # Returns     : exit code (0 = True, 1 = False, meaning search was cancelled)\n    #               stdout (output of search result)\n    ################################################################################\n\n    GetReportData() {\n        KEY=\"\"\n        VALID_CHARS=\"[:alnum:]/:;\\-,\\._\\[\\]\\n \"\n        if [ $# -eq 0 ]; then ExitFatal \"No parameters provided to GetReportData() function\"; fi\n\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --key)\n                    shift\n                    KEY=\"$1\"\n                ;;\n                --valid-chars)\n                    shift\n                    VALID_CHARS=\"$1\"\n                ;;\n                *)\n                    ExitFatal \"Invalid option provided to GetReportData() function\"\n                ;;\n            esac\n            # Go to next parameter\n            shift\n        done\n\n        if [ \"${REPORTFILE}\" = \"/dev/null\" ]; then\n            return 1\n        else\n            ${AWKBINARY} -v pattern=\"^${KEY}\" -F= '$1 ~ pattern {print $2}' ${REPORTFILE} | ${TRBINARY} -cd \"${VALID_CHARS}\" | ${TRBINARY} '[:blank:]' '__space__'\n        fi\n        return 0\n    }\n\n\n    ################################################################################\n    # Name        : HasCorrectFilePermissions()\n    # Description : Check file permissions\n    #\n    # Parameters  : $1 = Full path to file or directory\n    #               $2 = Permissions\n    # Returns     : exit code (0 = correct, 1 = not correct, 2 = file does not exist)\n    ################################################################################\n\n    HasCorrectFilePermissions() {\n        if [ $# -ne 2 ]; then Fatal \"Incorrect usage of HasCorrectFilePermissions\"; fi\n        CHECKFILE=\"$1\"\n        CHECKPERMISSION_FULL=\"$2\"\n        # Check for symlink\n        if [ -L ${CHECKFILE} ]; then\n            ShowSymlinkPath ${CHECKFILE}\n            if [ ! \"${SYMLINK}\" = \"\" ]; then CHECKFILE=\"${SYMLINK}\"; fi\n        fi\n        if [ ! -d ${CHECKFILE} -a ! -f ${CHECKFILE} ]; then\n            return 2\n        else\n            for CHECK_PERMISSION in ${CHECKPERMISSION_FULL}; do\n                DATA=$(echo ${CHECK_PERMISSION} | ${GREPBINARY} -E \"[rwx]\")\n                if [ $? -eq 0 ]; then\n                    # add a dummy character as first character so it looks like output is a normal file\n                    CHECK_PERMISSION=$(echo \"-${CHECK_PERMISSION}\" | ${AWKBINARY} '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\"%0o\",k)}')\n                fi\n\n                # Add leading zeros if necessary\n                CHECK_PERMISSION=$(echo \"${CHECK_PERMISSION}\" | ${AWKBINARY} '{printf \"%03d\",$1}')\n\n                # First try stat command\n                LogText \"Test: checking if file ${CHECKFILE} has the permissions set to ${CHECK_PERMISSION} (${CHECKPERMISSION_FULL}) or more restrictive\"\n                if [ -n \"${STATBINARY}\" ]; then\n                    case ${OS} in\n                        *BSD | \"macOS\")\n                            # BSD and macOS have no --format, only short notation\n                            DATA=$(${STATBINARY} -f \"%OLp\" ${CHECKFILE})\n                        ;;\n                        *)\n                            # busybox does not support format\n                            if [ ${SHELL_IS_BUSYBOX} -eq 0 ]; then\n                                DATA=$(${STATBINARY} --format=%a ${CHECKFILE})\n                            else\n                                DATA=$(${STATBINARY} -c %a ${CHECKFILE})\n                            fi\n                        ;;\n                    esac\n                fi\n\n                # See if we can use the find binary\n                if [ -z \"${DATA}\" ]; then\n                    case ${OS} in\n                        \"AIX\" | *BSD)\n                            Debug \"Skipping find command, as this operating system does not support -printf parameter\"\n                        ;;\n                        *)\n                            # Only use find when OS is NOT AIX and binaries are NOT busybox\n                            if [ -d \"${CHECKFILE}\" ]; then\n                                MAXDEPTH=\"-maxdepth 0\"\n                            else\n                                MAXDEPTH=\"\"\n                            fi\n\n                            if [ ${SHELL_IS_BUSYBOX} -eq 0 ]; then\n                                DATA=$(${FINDBINARY} \"${CHECKFILE}\" ${MAXDEPTH} -printf \"%m\")\n                            else\n                                DATA=$(${FINDBINARY} \"${CHECKFILE}\" ${MAXDEPTH} -exec stat -c %a {} \\;)\n                            fi\n                        ;;\n                    esac\n                fi\n\n                # Finally use ls command\n                if [ -z \"${DATA}\" ]; then\n                    # If 'file' is an directory, use -d\n                    if [ -d ${CHECKFILE} ]; then\n                        DATA=$(${LSBINARY} -d -l ${CHECKFILE} | cut -c 2-10)\n                    else\n                        DATA=$(${LSBINARY} -l ${CHECKFILE} | cut -c 2-10)\n                    fi\n                fi\n\n                # Convert permissions to octal when needed\n                case ${DATA} in\n                    [-r][-w][-x][-r][-w][-x][-r][-w][-x] )\n                        LogText \"Converting value ${DATA} to octal\"\n                        # add a dummy character as first character so it looks like output is a normal file\n                        DATA=$(echo \"-${DATA}\" | ${AWKBINARY} '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\"%0o\",k)}')\n                    ;;\n                esac\n\n                # Add leading zeros if necessary\n                DATA=$(echo \"${DATA}\" | ${AWKBINARY} '{printf \"%03d\",$1}')\n\n                if [ -n \"${DATA}\" ]; then\n                    if [ \"${DATA}\" -le \"${CHECK_PERMISSION}\" ]; then\n                        LogText \"Outcome: correct permissions (${DATA})\"\n                        return 0\n                    fi\n                else\n                    ReportException \"HasCorrectFilePermissions:02\" \"No data value found, which is unexpected\"\n                fi\n            done\n\n            LogText \"Outcome: permissions of file ${CHECKFILE} are not matching expected value (${DATA} != ${CHECK_PERMISSION})\"\n            # No match, return exit code 1\n            return 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : HasData()\n    # Description : Check for a filled variable\n    #\n    # Returns     : exit code (0 = True, 1 = False)\n    # Usage       : if HasData \"${FIND}\"; then\n    ################################################################################\n\n    HasData() {\n        if [ $# -eq 1 ]; then\n            if [ -n \"$1\" ]; then return 0; else return 1; fi\n        else\n            ExitFatal \"Function HasData called without parameters - look in log to determine where this happened, or use sh -x lynis to see all details.\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : InsertSection()\n    # Description : Show a section block on screen\n    #\n    # Returns     : <nothing>\n    # Usage       : InsertSection\n    ################################################################################\n\n    InsertSection() {\n        if [ ${QUIET} -eq 0 ]; then\n            echo \"\"\n            echo \"[+] ${SECTION}$1${NORMAL}\"\n            echo \"------------------------------------\"\n        fi\n        LogTextBreak\n        LogText \"Action: Performing tests from category: $1\"\n    }\n\n\n    ################################################################################\n    # Name        : InsertPlugionSection()\n    # Description : Insert section block for plugins (different color)\n    #\n    # Returns     : <nothing>\n    # Usage       : InsertPluginSection\n    ################################################################################\n\n    InsertPluginSection() {\n        if [ ${QUIET} -eq 0 ]; then\n            echo \"\"\n            echo \"[+] ${MAGENTA}$1${NORMAL}\"\n            echo \"------------------------------------\"\n        fi\n        LogText \"Action: Performing plugin tests\"\n    }\n\n\n    ################################################################################\n    # Name        : IsContainer()\n    # Description : Determine if we are running in a container\n    #\n    # Parameters  : <none>\n    # Returns     : exit code (0 = true, 1 = false)\n    #               variable: CONTAINER_TYPE\n    ################################################################################\n\n    IsContainer() {\n        FOUND=0\n        # Early on we can't use FileIsReadable yet\n        if [ -e /proc/1/cgroup ]; then\n            FIND=$(grep -i docker ${ROOTDIR}proc/1/cgroup 2> /dev/null)\n            if [ $? -eq 0 ]; then\n                LogText \"Result: found Docker in control groups (/proc/1/cgroup), so we are running in Docker container\"\n                CONTAINER_TYPE=\"Docker\"; FOUND=1\n                EXITCODE=0\n            fi\n        fi\n        if [ -e /proc/1/environ ]; then\n            FIND=$(grep -qa 'container=lxc' ${ROOTDIR}proc/1/environ 2> /dev/null)\n            if [ $? -eq 0 ]; then\n                LogText \"Result: found LXC in environment (/proc/1/environ), so we are running in LXC container\"\n                CONTAINER_TYPE=\"LXC\"; FOUND=1\n                EXITCODE=0\n            fi\n        fi\n        if [ ${FOUND} -eq 0 ]; then\n            CONTAINER_TYPE=\"\"\n            EXITCODE=1\n        fi\n        return ${EXITCODE}\n    }\n\n\n    ################################################################################\n    # Name        : IsDebug()\n    # Description : Check if --debug option is used to show more details\n    #\n    # Parameters  : <none>\n    # Returns     : exit code (0 = True, 1 = False)\n    ################################################################################\n\n    IsDebug() {\n        if [ ${DEBUG} -eq 1 ]; then return 0; else return 1; fi\n    }\n\n\n    ################################################################################\n    # Name        : IsDeveloperMode()\n    # Description : Check if we are in development mode (--developer)\n    #\n    # Parameters  : <none>\n    # Returns     : exit code (0 = True, 1 = False)\n    # Notes       : This is set with command line option or as a profile setting\n    ################################################################################\n\n    IsDeveloperMode() {\n        if [ ${DEVELOPER_MODE} -eq 1 ]; then return 0; else return 1; fi\n    }\n\n\n    ################################################################################\n    # Name        : IsDeveloperVersion()\n    # Description : Check if this version is development or stable release\n    #\n    # Parameters  : <none>\n    # Returns     : exit code (0 = True, 1 = False)\n    ################################################################################\n\n    IsDeveloperVersion() {\n        if [ \"${PROGRAM_RELEASE_TYPE}\" = \"pre-release\" ]; then return 0; else return 1; fi\n    }\n\n\n    ################################################################################\n    # Name        : IsEmpty()\n    # Description : Check for variable that has no data in it\n    #\n    # Returns     : exit code (0 = True, 1 = False)\n    # Usage       : if IsEmpty \"${FIND}\"; then\n    ################################################################################\n\n    IsEmpty() {\n        if [ $# -eq 0 ]; then\n            ExitFatal \"Function IsEmpty called without parameters - look in log to determine where this happened, or use sh -x lynis to see all details.\"\n        else\n            if [ -z \"$1\" ]; then return 0; else return 1; fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsRunning()\n    # Description : Check if a process is running\n    #\n    # Parameters  : $1 = search argument\n    #               $2 = optional arguments\n    # Returns     : 0 (process is running), 1 (process not running)\n    #               RUNNING (1 = running, 0 = not running) - will be deprecated\n    # Notes       : PSOPTIONS are declared globally, to prevent testing each call\n    #               Fallback is used on binaries as IsRunning is used for 'show' command\n    ################################################################################\n\n    IsRunning() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling IsRunning function\"; fi\n        pgrep_options=\"-x\"\n        search=\"\"\n        FIND=\"\"\n        PSOPTIONS=\"\"\n        PARTIAL_SEARCH=1\n\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --full)\n                    pgrep_options=\"-f\" # replace -x with -f\n                    PARTIAL_SEARCH=0\n                ;;\n                --user)\n                    shift\n                    users=\"$1\"\n                ;;\n                *)\n                    search=\"$1\"\n                ;;\n            esac\n            shift  # Go to next parameter\n        done\n\n        if [ -z \"${search}\" ]; then ExitFatal \"Missing process to search for when using IsRunning function\"; fi\n        RUNNING=0\n        if [ -x \"${PGREPBINARY}\" ] && [ \"${OS}\" != \"AIX\" ]; then\n            # When --user is used, perform a search using the -u option\n            # Initialize users for strict mode\n            if [ -n \"${users:-}\" ]; then\n                for u in ${users}; do\n                    user_uid=$(getent passwd \"${u}\" 2> /dev/null | ${AWKBINARY:-awk} -F: '{print $3}')\n                    # Only perform search if user exists and we had no match yet\n                    if [ -n \"${user_uid}\" ]; then\n                        if [ -z \"${FIND}\" ]; then\n                            LogText \"Performing pgrep scan using uid ${user_uid}\"\n                            FIND=$(${PGREPBINARY:-pgrep} ${pgrep_options} -u \"${user_uid}\" \"${search}\" | ${TRBINARY:-tr} '\\n' ' ')\n                        fi\n                    fi\n                done\n            else\n                LogText \"Performing pgrep scan without uid\"\n                FIND=$(${PGREPBINARY:-pgrep} ${pgrep_options} \"${search}\" | ${TRBINARY:-tr} '\\n' ' ')\n            fi\n        else\n            if [ \"${SHELL_IS_BUSYBOX}\" -eq 1 ]; then\n                # This search is not foolproof\n                LogText \"Performing simple ps scan (busybox)\"\n                PSOPTIONS=\" -o args=\"\n                FIND=$(${PSBINARY:-ps} ${PSOPTIONS} | ${GREPBINARY:-grep} -E \"( |/)${search}\" | ${GREPBINARY:-grep} -v \"grep\")\n            else\n                if [ -n \"${users}\" ]; then\n                    for u in ${users}; do\n                        user_uid=$(getent passwd \"${u}\" 2> /dev/null | ${AWKBINARY:-awk} -F: '{print $3}')\n                        # Only perform search if user exists and we had no match yet\n                        if [ -n \"${user_uid}\" ]; then\n                            if [ -z \"${FIND}\" ]; then\n                                if [ ${PARTIAL_SEARCH} -eq 1 ]; then\n                                    LogText \"Performing ps scan using partial match and for uid ${user_uid}\"\n                                    FIND=$(${PSBINARY:-ps} -u \"${user_uid}\" -o comm= \"${search}\" | ${AWKBINARY:-awk} -v pattern=\"${search}\" '$0 ~ pattern {print}')\n                                else\n                                    LogText \"Performing ps scan using exact match and for uid ${user_uid}\"\n                                    FIND=$(${PSBINARY:-ps} -u \"${user_uid}\" -o comm= \"${search}\" | ${AWKBINARY:-awk} -v pattern=\"^${search}$\" '$0 ~ pattern {print}')\n                                fi\n                            fi\n                        fi\n                    done\n                else\n                    case \"${OS}\" in\n                        \"Linux\")\n                            PSOPTIONS=\" -o args= -C ${search}\"\n                        ;;\n                    esac\n                    if [ ${PARTIAL_SEARCH} -eq 1 ]; then\n                        LogText \"Performing ps scan using partial match and without uid\"\n                        FIND=$(${PSBINARY:-ps} ${PSOPTIONS} | ${AWKBINARY:-awk} -v pattern=\"${search}\" '$0 ~ pattern {print}')\n                    else\n                        LogText \"Performing ps scan using exact match and without uid\"\n                        FIND=$(${PSBINARY:-ps} ${PSOPTIONS} | ${AWKBINARY:-awk} -v pattern=\"^${search}$\" '$0 ~ pattern {print}')\n                    fi\n                fi\n            fi\n        fi\n\n        if [ -n \"${FIND}\" ]; then\n            RUNNING=1\n            LogText \"IsRunning: process '${search}' found (${FIND})\"\n            return 0\n        else\n            LogText \"IsRunning: process '${search}' not found\"\n            return 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsNotebook\n    # Description : Check if file or directory is owned by root\n    # Returns     : exit code (0 = True, 1 = False, 255 = Unknown)\n    ################################################################################\n\n    IsNotebook() {\n        FIND=$(which laptop-detect 2> /dev/null | grep -v \"no [^ ]* in \")\n        if [ -n \"${FIND}\" ]; then\n            Debug \"Testing if we are a notebook\"\n            laptop-detect\n            if [ $? -eq 0 ]; then SYSTEM_IS_NOTEBOOK=1; Debug \"System is a notebook according to laptop-detect\"\n            elif [ $? -eq 1 ]; then SYSTEM_IS_NOTEBOOK=0; Debug \"System is a NOT a notebook according to laptop-detect\"; fi\n            Report \"notebook=${SYSTEM_IS_NOTEBOOK}\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsOwnedByRoot\n    # Description : Check if file or directory is owned by root\n    # Returns     : 0 (true), 1 (false), or 255 (unknown)\n    ################################################################################\n\n    IsOwnedByRoot() {\n        PERMS=\"\"\n        if [ $# -eq 1 ]; then\n            FILE=\"$1\"\n            case $OS in\n                \"AIX\")\n                    if [ ! \"${ISTATBINARY}\" = \"\" ]; then PERMS=$(${ISTATBINARY} ${FILE} | sed \"s/Owner: //\" | sed \"s/[a-zA-Z() ]//g\"); fi\n                ;;\n                \"Linux\")\n                    if [ ! \"${STATBINARY}\" = \"\" ]; then PERMS=$(${STATBINARY} -c \"%u:%g\" ${FILE}); fi\n                ;;\n                \"FreeBSD\")\n                    if [ ! \"${STATBINARY}\" = \"\" ]; then PERMS=$(${STATBINARY} -f \"%u:%g\" ${FILE}); fi\n                ;;\n            esac\n            # Fallback with ls (for other platforms, or when a test did not reveal any output)\n            if [ \"${PERMS}\" = \"\" ]; then\n                PERMS=$(ls -n ${FILE} | ${AWKBINARY} '{ print $3\":\"$4 }')\n            fi\n        else\n            ReportException \"IsOwnedByRoot\" \"Functions needs 1 argument\"\n            return 255\n        fi\n        if [ \"${PERMS}\" = \"0:0\" ]; then\n            if IsDeveloperMode; then LogText \"Debug: found incorrect file permissions on ${FILE}\"; fi\n            return 0\n        else\n            return 1\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsVerbose()\n    # Description : Check if --verbose option is used to show more details on screen\n    #\n    # Parameters  : <none>\n    # Returns     : exit code (0 =true, 1 =false)\n    ################################################################################\n\n    IsVerbose() {\n        if [ ${VERBOSE} -eq 1 ]; then return 0; else return 1; fi\n    }\n\n\n    ################################################################################\n    # Name        : IsVirtualMachine()\n    # Description : Determine whether it is a virtual machine\n    # Parameters  : <none>\n    # Returns     : exit code (0 = True, 1 = False, 2 = Unknown)\n    #               variable: ISVIRTUALMACHINE (0-2)\n    #               variable: VMTYPE\n    #               variable: VMFULLTYPE\n    ################################################################################\n\n    IsVirtualMachine() {\n        LogText \"Test: Determine if this system is a virtual machine\"\n        # 0 = no, 1 = yes, 2 = unknown\n        ISVIRTUALMACHINE=2; VMTYPE=\"unknown\"; VMFULLTYPE=\"Unknown\"\n        SHORT=\"\"\n\n        if [ ${SKIP_VM_DETECTION} -eq 1 ]; then\n            return 2\n        fi\n\n        # lxc environ detection\n        if [ -z \"${SHORT}\" ]; then\n            if [ -f /proc/1/environ ]; then\n                FIND=$(grep -qa 'container=lxc' /proc/1/environ 2> /dev/null)\n                if [ $? -eq 0 ]; then\n                    SHORT=lxc\n                    LogText \"Result: found ${SHORT}\"\n                fi\n            fi\n        else\n            LogText \"Result: skipped lxc environ detection test, as we already found machine type\"\n        fi\n\n        # facter\n        if [ -z \"${SHORT}\" ]; then\n            if [ -x /usr/bin/facter ] || [ -x /usr/local/bin/facter ]; then\n                case \"$(facter is_virtual)\" in\n                \"true\")\n                    SHORT=$(facter virtual)\n                    LogText \"Result: found ${SHORT}\"\n                ;;\n                \"false\")\n                    LogText \"Result: facter says this machine is not a virtual\"\n                ;;\n                esac\n            else\n                LogText \"Result: facter utility not found\"\n            fi\n        else\n            LogText \"Result: skipped facter test, as we already found machine type\"\n        fi\n\n        # systemd\n        if [ -z \"${SHORT}\" ]; then\n            if [ -x /usr/bin/systemd-detect-virt ]; then\n                LogText \"Test: trying to guess virtualization technology with systemd-detect-virt\"\n                FIND=$(/usr/bin/systemd-detect-virt)\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found ${FIND}\"\n                    SHORT=\"${FIND}\"\n                fi\n            else\n                LogText \"Result: systemd-detect-virt not found\"\n            fi\n        else\n            LogText \"Result: skipped systemd test, as we already found machine type\"\n        fi\n\n        # lscpu\n        # Values: VMware\n        if [ -z \"${SHORT}\" ]; then\n            if [ -x /usr/bin/lscpu ]; then\n                LogText \"Test: trying to guess virtualization with lscpu\"\n                FIND=$(lscpu | grep -i \"^Hypervisor Vendor\" | awk -F: '{ print $2 }' | sed 's/ //g')\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found ${FIND}\"\n                    SHORT=\"${FIND}\"\n                else\n                    LogText \"Result: can't find hypervisor vendor with lscpu\"\n                fi\n            else\n                LogText \"Result: lscpu not found\"\n            fi\n        else\n            LogText \"Result: skipped lscpu test, as we already found machine type\"\n        fi\n\n        # dmidecode\n        # Values: VMware Virtual Platform / VirtualBox\n        if [ -z \"${SHORT}\" ]; then\n            # Try to find dmidecode in case we did not check binaries (e.g. lynis show environment)\n            if [ ${CHECK_BINARIES} -eq 0 ]; then DMIDECODEBINARY=$(command -v dmidecode 2> /dev/null); fi\n            if [ -n \"${DMIDECODEBINARY}\" -a -x \"${DMIDECODEBINARY}\" -a ${PRIVILEGED} -eq 1 ]; then\n                LogText \"Test: trying to guess virtualization with dmidecode\"\n                FIND=$(${DMIDECODEBINARY} -s system-product-name | awk '{ print $1 }')\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found ${FIND}\"\n                    SHORT=\"${FIND}\"\n                else\n                    LogText \"Result: can't find product name with dmidecode\"\n                fi\n            else\n                LogText \"Result: dmidecode not found (or no access)\"\n            fi\n        else\n            LogText \"Result: skipped dmidecode test, as we already found machine type\"\n        fi\n\n        # Other options\n        # SaltStack: salt-call grains.get virtual\n        # < needs snippet >\n\n        # Try common guest processes\n        if [ -z \"${SHORT}\" ]; then\n            LogText \"Test: trying to guess virtual machine type by running processes\"\n\n            # VMware\n            if IsRunning vmware-guestd; then SHORT=\"vmware\"\n            elif IsRunning vmtoolsd; then SHORT=\"vmware\"\n            fi\n\n            # VirtualBox based on guest services\n            if IsRunning vboxguest-service; then SHORT=\"virtualbox\"\n            elif IsRunning VBoxClient; then SHORT=\"virtualbox\"\n            elif IsRunning VBoxService; then SHORT=\"virtualbox\"\n            fi\n        else\n            LogText \"Result: skipped processes test, as we already found platform\"\n        fi\n\n        # Amazon EC2\n        if [ -z \"${SHORT}\" ]; then\n            LogText \"Test: checking specific files for Amazon\"\n            if [ -f /etc/ec2_version -a -s /etc/ec2_version ]; then\n                SHORT=\"amazon-ec2\"\n            else\n                LogText \"Result: system not hosted on Amazon\"\n            fi\n        else\n            LogText \"Result: skipped Amazon EC2 test, as we already found platform\"\n        fi\n\n        # sysctl values\n        if [ -z \"${SHORT}\" ]; then\n            LogText \"Test: trying to guess virtual machine type by sysctl keys\"\n\n            # FreeBSD: hw.hv_vendor (remains empty for VirtualBox)\n            # NetBSD: machdep.dmi.system-product\n            # OpenBSD: hw.product\n            FIND=$(sysctl -a 2> /dev/null | grep -E \"(hw.product|machdep.dmi.system-product)\" | head -n 1 | sed 's/ = /=/' | awk -F= '{ print $2 }')\n            if [ ! \"${FIND}\" = \"\" ]; then\n                SHORT=\"${FIND}\"\n            fi\n        else\n            LogText \"Result: skipped sysctl test, as we already found platform\"\n        fi\n\n        # lshw\n        if [ -z \"${SHORT}\" ]; then\n            if [ ${PRIVILEGED} -eq 1 ]; then\n                if [ -x /usr/bin/lshw ]; then\n                    LogText \"Test: trying to guess virtualization with lshw\"\n                    FIND=$(lshw -quiet -class system 2> /dev/null | awk '{ if ($1==\"product:\") { print $2 }}')\n                    if HasData \"${FIND}\"; then\n                        LogText \"Result: found ${FIND}\"\n                        SHORT=\"${FIND}\"\n                    fi\n                else\n                    LogText \"Result: lshw not found\"\n                fi\n            else\n                LogText \"Result: skipped lshw test, as we are non-privileged and need more permissions to run lshw\"\n            fi\n        else\n            LogText \"Result: skipped lshw test, as we already found machine type\"\n        fi\n\n        # Check if we caught some string along all tests\n        if [ -n \"${SHORT}\" ]; then\n            # Lowercase and see if we found a match\n            SHORT=$(echo ${SHORT} | awk '{ print $1 }' | tr '[:upper:]' '[:lower:]')\n\n                case ${SHORT} in\n                    amazon-ec2)         ISVIRTUALMACHINE=1; VMTYPE=\"amazon-ec2\";      VMFULLTYPE=\"Amazon AWS EC2 Instance\"                 ;;\n                    bochs)              ISVIRTUALMACHINE=1; VMTYPE=\"bochs\";           VMFULLTYPE=\"Bochs CPU emulation\"                     ;;\n                    docker)             ISVIRTUALMACHINE=1; VMTYPE=\"docker\";          VMFULLTYPE=\"Docker container\"                        ;;\n                    kvm)                ISVIRTUALMACHINE=1; VMTYPE=\"kvm\";             VMFULLTYPE=\"KVM\"                                     ;;\n                    lxc)                ISVIRTUALMACHINE=1; VMTYPE=\"lxc\";             VMFULLTYPE=\"Linux Containers\"                        ;;\n                    lxc-libvirt)        ISVIRTUALMACHINE=1; VMTYPE=\"lxc-libvirt\";     VMFULLTYPE=\"libvirt LXC driver (Linux Containers)\"   ;;\n                    microsoft)          ISVIRTUALMACHINE=1; VMTYPE=\"microsoft\";       VMFULLTYPE=\"Microsoft Virtual PC\"                    ;;\n                    openvz)             ISVIRTUALMACHINE=1; VMTYPE=\"openvz\";          VMFULLTYPE=\"OpenVZ\"                                  ;;\n                    oracle|virtualbox)  ISVIRTUALMACHINE=1; VMTYPE=\"virtualbox\";      VMFULLTYPE=\"Oracle VM VirtualBox\"                    ;;\n                    qemu)               ISVIRTUALMACHINE=1; VMTYPE=\"qemu\";            VMFULLTYPE=\"QEMU\"                                    ;;\n                    systemd-nspawn)     ISVIRTUALMACHINE=1; VMTYPE=\"systemd-nspawn\";  VMFULLTYPE=\"Systemd Namespace container\"             ;;\n                    uml)                ISVIRTUALMACHINE=1; VMTYPE=\"uml\";             VMFULLTYPE=\"User-Mode Linux (UML)\"                   ;;\n                    vmware)             ISVIRTUALMACHINE=1; VMTYPE=\"vmware\";          VMFULLTYPE=\"VMware product\"                          ;;\n                    xen)                ISVIRTUALMACHINE=1; VMTYPE=\"xen\";             VMFULLTYPE=\"XEN\"                                     ;;\n                    zvm)                ISVIRTUALMACHINE=1; VMTYPE=\"zvm\";             VMFULLTYPE=\"IBM z/VM\"                                ;;\n                    openstack)          ISVIRTUALMACHINE=1; VMTYPE=\"openstack\";       VMFULLTYPE=\"Openstack Nova\"                          ;;\n                    *)                  LogText \"Result: Unknown virtualization type, so most likely system is physical\"                   ;;\n                esac\n        fi\n\n        # Check final status\n        if [ ${ISVIRTUALMACHINE} -eq 1 ]; then\n            LogText \"Result: found virtual machine (type: ${VMTYPE}, ${VMFULLTYPE})\"\n            Report \"vm=1\"\n            Report \"vmtype=${VMTYPE}\"\n        elif [ ${ISVIRTUALMACHINE} -eq 2 ]; then\n            LogText \"Result: unknown if this system is a virtual machine\"\n            Report \"vm=2\"\n        else\n            LogText \"Result: system seems to be non-virtual\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsWorldReadable()\n    # Description : Determines if a file is readable for all users (world)\n    #\n    # Input       : $1 = path (string)\n    # Returns     : exit code (0 = readable, 1 = not readable, 255 = error)\n    # Usage       : if IsWorldReadable /etc/motd; then echo \"File is readable\"; fi\n    ################################################################################\n\n    IsWorldReadable() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling IsWorldReadable function\"; fi\n        sFILE=$1\n        # Check for symlink\n        if [ -L ${sFILE} ]; then\n            ShowSymlinkPath ${sFILE}\n            if [ ! \"${SYMLINK}\" = \"\" ]; then sFILE=\"${SYMLINK}\"; fi\n        fi\n        if [ -f ${sFILE} -o -d ${sFILE} ]; then\n            FINDVAL=$(ls -ld ${sFILE} | cut -c 8)\n            if [ \"${FINDVAL}\" = \"r\" ]; then return 0; else return 1; fi\n        else\n            return 255\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsWorldExecutable()\n    # Description : Determines if a file is executable for all users (world)\n    #\n    # Input       : $1 = path (string)\n    # Returns     : exit code (0 = executable, 1 = not executable, 255 = error)\n    # Usage       : if IsWorldExecutable /bin/ps; then echo \"File is executable\"; fi\n    ################################################################################\n\n    # Function IsWorldExecutable\n    IsWorldExecutable() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling IsWorldExecutable function\"; fi\n        sFILE=$1\n        # Check for symlink\n        if [ -L ${sFILE} ]; then\n            ShowSymlinkPath ${sFILE}\n            if [ ! \"${SYMLINK}\" = \"\" ]; then sFILE=\"${SYMLINK}\"; fi\n        fi\n        if [ -f ${sFILE} -o -d ${sFILE} ]; then\n            FINDVAL=$(ls -l ${sFILE} | cut -c 10)\n            if [ \"${FINDVAL}\" = \"x\" ]; then return 0; else return 1; fi\n        else\n            return 255\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : IsWorldWritable()\n    # Description : Determines if a file is writable for all users\n    #\n    # Parameters  : $1 = path\n    # Returns     : exit code (0 = writable, 1 = not writable, 255 = error)\n    # Usage       : if IsWorldWritable /etc/motd; then echo \"File is writable\"; fi\n    ################################################################################\n\n    IsWorldWritable() {\n        if [ $# -eq 0 ]; then ExitFatal \"Missing parameter when calling IsWorldWritable function\"; fi\n        sFILE=$1\n        FileIsWorldWritable=\"\"\n        # Check for symlink\n        if [ -L ${sFILE} ]; then\n            ShowSymlinkPath ${sFILE}\n            if [ ! \"${SYMLINK}\" = \"\" ]; then sFILE=\"${SYMLINK}\"; fi\n        fi\n        # Only check if target is a file or directory\n        if [ -f ${sFILE} -o -d ${sFILE} ]; then\n            FINDVAL=$(ls -ld ${sFILE} | cut -c 9)\n            if IsDeveloperMode; then Debug \"File mode of ${sFILE} is ${FINDVAL}\"; fi\n            if [ \"${FINDVAL}\" = \"w\" ]; then return 0; else return 1; fi\n        else\n            return 255\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : LogText()\n    # Description : Function logtext (redirect data ($1) to log file)\n    #\n    # Parameters  : $1 = text (string)\n    # Returns     : <nothing>\n    # Usage       : LogText \"This line goes into the log file\"\n    ################################################################################\n\n    LogText() {\n        if [ ! \"${LOGFILE}\" = \"\" -a ${LOGTEXT} -eq 1 ]; then CDATE=$(date \"+%Y-%m-%d %H:%M:%S\"); echo \"${CDATE} $1\" >> ${LOGFILE}; fi\n    }\n\n\n    ################################################################################\n    # Name        : LogTextBreak()\n    # Description : Add a separator to log file between sections, tests etc\n    # Returns     : <nothing>\n    ################################################################################\n\n    LogTextBreak() {\n        if [ ! \"${LOGFILE}\" = \"\" -a ${LOGTEXT} -eq 1 ]; then\n            CDATE=$(date \"+%Y-%m-%d %H:%M:%S\")\n            echo \"${CDATE} ====\" >> ${LOGFILE}\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : PackageIsInstalled()\n    # Description : Determines if a package is installed\n    # Returns     : exit code\n    # Notes       : this function is not used yet, but created in advance to allow\n    #               the addition of support for all operating systems\n    ################################################################################\n\n    PackageIsInstalled() {\n        exit_code=255\n\n        # First parameter is package name (or __dummy__ for initial test to see if package manager is available and works as expected)\n        if [ $# -eq 1 ]; then\n            package=\"$1\"\n        else\n            Fatal \"Incorrect usage of PackageIsInstalled function\"\n        fi\n\n        if [ -n \"${DNFBINARY}\" ]; then\n            output=$(${DNFBINARY} --quiet --cacheonly --noplugins --assumeno info --installed ${package} > /dev/null 2>&1)\n            exit_code=$?\n        elif [ -n \"${DPKGBINARY}\" ]; then\n            output=$(${DPKGBINARY} -l ${package} 2> /dev/null | ${GREPBINARY} \"^ii\")\n            exit_code=$?\n        elif [ -n \"${EQUERYBINARY}\" ]; then\n            output=$(${EQUERYBINARY} --quiet ${package} > /dev/null 2>&1)\n            exit_code=$?  # 0=package installed, 3=package not installed\n        elif [ -n \"${PACMANBINARY}\" ]; then\n            output=$(${PACMANBINARY} -Qs ${PKG} | grep \"local/${PKG} \" >/dev/null 2>&1)\n            exit_code=$?  # 0=package installed, 1=package not installed\n        elif [ -n \"${PKG_BINARY}\" ]; then\n            output=$(${PKG_BINARY} -N info ${package} >/dev/null 2>&1)\n            exit_code=$?  # 0=package installed, 70=invalid package\n        elif [ -n \"${PKGINFOBINARY}\" ]; then\n            output=$(${PKGINFOBINARY} -q -e ${package} >/dev/null 2>&1)\n            exit_code=$?  # 0=package installed, 1=package not installed\n        # Slackware also has RPM for some reason and that's why this test precedes the RPMBINARY test\n        elif [ \"${OS_NAME}\" = \"Slackware Linux\" -a -d \"${ROOTDIR}/var/lib/pkgtools/packages\" ]; then\n            output=$( ls ${ROOTDIR}/var/lib/pkgtools/packages/ 2> /dev/null | ${GREPBINARY} \"^${package}-[^-]\\+-[^-]\\+-[^-]\\+$\" )\n            exit_code=$?\n        elif [ -n \"${RPMBINARY}\" ]; then\n            output=$(${RPMBINARY} --quiet -q ${package} > /dev/null 2>&1)\n            exit_code=$?\n        elif [ -n \"${SWUPDBINARY}\" ]; then\n            output=$(${SWUPDBINARY} bundle-list > /dev/null 2>&1 | ${GREPBINARY} \"^${package}$\")\n            exit_code=$?\n        elif [ -n \"${ZYPPERBINARY}\" ]; then\n            output=$(${ZYPPERBINARY} --quiet --non-interactive search --installed -i ${package} 2> /dev/null | grep \"^i\")\n            if [ -n \"${output}\" ]; then exit_code=0; else exit_code=1; fi\n        elif [ -n \"${XBPSBINARY}\" ]; then\n            output=$(${XBPSBINARY} ${package} 2> /dev/null | ${GREPBINARY} \"^ii\")\n            exit_code=$?\n        elif [ -n \"${APKBINARY}\" ]; then\n            output=$(${APKBINARY} list --installed ${package} 2> /dev/null | ${GREPBINARY} ${package})\n            exit_code=$?\n        else\n            if [ \"${package}\" != \"__dummy__\" ]; then\n                ReportException \"PackageIsInstalled:01 (test=${TEST_NO:-unknown})\"\n            fi\n        fi\n\n        # Give thumbs up if dummy package is used during initial test for package manager availability\n        if [ \"${package}\" = \"__dummy__\" ]; then\n            # There should be no positive match on this dummy package\n            if [ ${exit_code} -eq 0 ]; then\n                exit_code=1\n            elif [ ${exit_code} -eq 255 ]; then\n                exit_code=1\n            else\n                exit_code=0\n            fi\n        fi\n\n        return ${exit_code}\n    }\n\n\n    ################################################################################\n    # Name        : ParseProfiles()\n    # Description : Check file permissions and parse data from profiles\n    # Parameters  : <none>\n    # Returns     : <nothing>\n    ################################################################################\n\n    ParseProfiles() {\n        SafePerms ${INCLUDEDIR}/profiles\n        . ${INCLUDEDIR}/profiles\n    }\n\n\n    ################################################################################\n    # Name        : ParseTestValues()\n    # Description : Parse values from a specific test\n    #\n    # Parameters  : $1 = service (e.g. ssh)\n    # Returns     : CHECK_VALUES_ARRAY variable\n    ################################################################################\n\n    ParseTestValues() {\n        RETVAL=1\n        FOUND=0\n        CHECK_VALUES_ARRAY=\"\"\n        if [ $# -gt 0 -a ! \"${CHECK_OPTION_ARRAY}\" = \"\" ]; then\n            for I in ${CHECK_OPTION_ARRAY}; do\n                Debug \"Array value: ${I}\"\n                SPLIT=$(echo ${I} | sed 's/,/\\n/g')\n                for ITEM in ${SPLIT}; do\n                    FUNCTION=\"\"\n                    VALUE=\"\"\n                    SEARCH=\"\"\n                    SERVICE=\"\"\n                    ITEM_KEY=$(echo ${ITEM} | awk -F: '{print $1}')\n                    ITEM_VALUE=$(echo ${ITEM} | awk -F: '{print $2}')\n                    Debug \"Array item: ${ITEM_KEY} with value ${ITEM_VALUE}\"\n                    case ${ITEM_KEY} in\n                        \"function\")\n                            case ${ITEM_VALUE} in\n                                \"equals\")\n                                    FUNCTION=\"eq\"\n                                ;;\n                            esac\n                        ;;\n                        \"service\")\n                            if [ \"${ITEM_VALUE}\" = \"$1\" ]; then\n                                FOUND=1\n                            fi\n                        ;;\n                        \"value\")\n                            VALUE=\"${ITEM_VALUE}\"\n                        ;;\n                        *)\n                            echo \"Incorrect call to function ParseTestValues\"; ExitFatal\n                        ;;\n                    esac\n                    if [ ${FOUND} -eq 1 ]; then\n                        CHECK_VALUES_ARRAY=\"${CHECK_VALUES_ARRAY} ${SEARCH}:${VALUE}:${FUNCTION}:\"\n                        FOUND=0\n                    fi\n                done\n            done\n            RETVAL=1\n        fi\n        return ${RETVAL}\n    }\n\n\n    ################################################################################\n    # Name        : ParseNginx()\n    # Description : Parse nginx configuration lines\n    #\n    # Parameters  : $1 = file (should be readable and tested upfront)\n    # Returns     : <nothing>\n    ################################################################################\n\n    ParseNginx() {\n        COUNT=0\n        BREADCRUMB=\"\"\n        if [ $# -eq 0 ]; then ExitFatal \"No arguments provided to ParseNginx()\"; fi\n        CONFIG_FILE=$1\n\n        # Create temporary files\n        CreateTempFile || ExitFatal \"Could not create temporary file\"\n        TMP_NGINX_FILE_RAW=\"${TEMP_FILE}\"\n        CreateTempFile || ExitFatal \"Could not create temporary file\"\n        TMP_NGINX_FILE=\"${TEMP_FILE}\"\n\n        # Strip out spaces, tabs and line breaks\n        awk '{$1=$1;print $0}' ${CONFIG_FILE} > ${TMP_NGINX_FILE_RAW}\n        # Now clean up the file further (combine lines, remove commented lines and empty lines)\n        sed 's#\\\\$##g' ${TMP_NGINX_FILE_RAW} | grep -v \"^#\" | grep -v \"^$\" > ${TMP_NGINX_FILE}\n\n        LogText \"Action: parsing configuration file ${CONFIG_FILE}\"\n        COUNT=$(( COUNT + 1))\n        FIND=$(sed 's/ /:space:/g' ${TMP_NGINX_FILE})\n        DEPTH=0\n        for I in ${FIND}; do\n            I=$(echo ${I} | sed 's/:space:/ /g' | sed 's/;$//' | sed 's/ #.*$//')\n            OPTION=$(echo ${I} | awk '{ print $1 }')\n            # Use quotes here to prevent wildcard expansion\n            VALUE=$(echo \"${I}\"| cut -d' ' -f2-)\n            LogText \"Result: found option ${OPTION} in ${CONFIG_FILE} with value '${VALUE}'\"\n            STORE_SETTING=1\n            case ${OPTION} in\n                \"events\")\n                    BREADCRUMB=\"${BREADCRUMB}/events\"\n                    DEPTH=$(( DEPTH + 1))\n                    STORE_SETTING=0\n                    NGINX_EVENTS_COUNTER=$(( NGINX_EVENTS_COUNTER + 1 ))\n                ;;\n                \"http\")\n                    BREADCRUMB=\"${BREADCRUMB}/http\"\n                    DEPTH=$(( DEPTH + 1))\n                    STORE_SETTING=0\n                    NGINX_HTTP_COUNTER=$(( NGINX_HTTP_COUNTER + 1 ))\n                ;;\n                \"location\")\n                    BREADCRUMB=\"${BREADCRUMB}/location\"\n                    DEPTH=$(( DEPTH + 1))\n                    STORE_SETTING=0\n                    NGINX_LOCATION_COUNTER=$(( NGINX_LOCATION_COUNTER + 1 ))\n                ;;\n                \"server\")\n                    BREADCRUMB=\"${BREADCRUMB}/server\"\n                    DEPTH=$(( DEPTH + 1))\n                    STORE_SETTING=0\n                    NGINX_SERVER_COUNTER=$(( NGINX_SERVER_COUNTER + 1 ))\n                ;;\n                \"}\")\n                    BREADCRUMB=$(echo ${BREADCRUMB} | awk -F/ 'sub(FS $NF,x)')\n                    DEPTH=$(( DEPTH - 1))\n                    STORE_SETTING=0\n                ;;\n                access_log)\n                    if [ \"${VALUE}\" = \"off\" ]; then\n                        LogText \"Result: found logging disabled for one virtual host\"\n                        NGINX_ACCESS_LOG_DISABLED=1\n                    else\n                        if [ ! \"${VALUE}\" = \"\" ]; then\n                            # If multiple values follow, select first one\n                            VALUE=$(echo ${VALUE} | awk '{ print $1 }')\n                            # Find both, log files provided with full or relative path\n                            if [ ! -f ${VALUE} -a ! -f \"${CONFIG_FILE%nginx.conf}${VALUE}\" ]; then\n                                LogText \"Result: could not find log file ${VALUE} referenced in nginx configuration\"\n                                NGINX_ACCESS_LOG_MISSING=1\n                            fi\n                        fi\n                    fi\n                ;;\n                # Headers\n                add_header)\n                    HEADER=$(echo ${VALUE} | awk '{ print $1 }')\n                    HEADER_VALUE=$(echo ${VALUE} | cut -d' ' -f2-)\n                    LogText \"Result: found header ${HEADER} with value ${HEADER_VALUE}\"\n                    #Report \"nginx_header[]=${HEADER}|${HEADER_VALUE}|\"\n                ;;\n                alias)\n                    NGINX_ALIAS_FOUND=1\n                ;;\n                allow)\n                    NGINX_ALLOW_FOUND=1\n                ;;\n                autoindex)\n                ;;\n                deny)\n                    NGINX_DENY_FOUND=1\n                ;;\n                expires)\n                    NGINX_EXPIRES_FOUND=1\n                ;;\n                error_log)\n                    # Check if debug is appended\n                    FIND=$(echo ${VALUE} | awk '{ if ($2==\"debug\") { print 1 } else { print 0 }}')\n                    if [ ${FIND} -eq 1 ]; then\n                        NGINX_ERROR_LOG_DEBUG=1\n                    fi\n                    # Check if log file exists\n                    FILE=$(echo ${VALUE} | awk '{ print $1 }')\n                    if [ ! \"${FILE}\" = \"\" ]; then\n                        # Find both, log files provided with full or relative path\n                        if [ ! -f ${FILE} -a ! -f \"${CONFIG_FILE%nginx.conf}${FILE}\" ]; then\n                            NGINX_ERROR_LOG_MISSING=1\n                        fi\n                    else\n                        LogText \"Warning: did not find a filename after error_log in nginx configuration\"\n                    fi\n                ;;\n                error_page)\n                ;;\n                fastcgi_intercept_errors)\n                ;;\n                fastcgi_param)\n                    NGINX_FASTCGI_FOUND=1\n                    NGINX_FASTCGI_PARAMS_FOUND=1\n                ;;\n                fastcgi_pass)\n                    NGINX_FASTCGI_FOUND=1\n                    NGINX_FASTCGI_PASS_FOUND=1\n                ;;\n                fastcgi_pass_header)\n                ;;\n                include)\n                    if [ -f \"${VALUE}\" ]; then\n                        FOUND=0\n                        for CONF in ${NGINX_CONF_FILES}; do\n                            if [ \"${CONF}\" = \"${VALUE}\" ]; then FOUND=1; LogText \"Found this file already in our configuration files array, not adding to queue\"; fi\n                        done\n                        for CONF in ${NGINX_CONF_FILES_ADDITIONS}; do\n                            if [ \"${CONF}\" = \"${VALUE}\" ]; then FOUND=1; LogText \"Found this file already in our configuration files array (additions), not adding to queue\"; fi\n                        done\n                        if [ ${FOUND} -eq 0 ]; then NGINX_CONF_FILES_ADDITIONS=\"${NGINX_CONF_FILES_ADDITIONS} ${VALUE}\"; fi\n                    # Check if include value is a relative path only\n                    elif [ -f \"${CONFIG_FILE%nginx.conf}${VALUE%;*}\" ]; then\n                        VALUE=\"${CONFIG_FILE%nginx.conf}${VALUE}\"\n                        FOUND=0\n                        for CONF in ${NGINX_CONF_FILES}; do\n                            if [ \"${CONF}\" = \"${VALUE}\" ]; then FOUND=1; LogText \"Found this file already in our configuration files array, not adding to queue\"; fi\n                        done\n                        for CONF in ${NGINX_CONF_FILES_ADDITIONS}; do\n                            if [ \"${CONF}\" = \"${VALUE}\" ]; then FOUND=1; LogText \"Found this file already in our configuration files array (additions), not adding to queue\"; fi\n                        done\n                        if [ ${FOUND} -eq 0 ]; then NGINX_CONF_FILES_ADDITIONS=\"${NGINX_CONF_FILES_ADDITIONS} ${VALUE}\"; fi\n                    # Check for additional config files included as follows\n                    # \"include sites-enabled/*.conf\" (relative path)\n                    # \"include /etc/nginx/sites-enabled/*.conf\" (absolute path)\n                    elif [ $(echo \"${VALUE}\" | grep -F -c \"*.conf\") -gt 0 ]; then\n                        # Check if path is absolute or relative\n                        case $VALUE in\n                            /*)\n                                # Absolute path, so wildcard pattern is already correct\n                                CONF_WILDCARD=${VALUE%;*}\n                            ;;\n                            *)\n                                # Relative path, so construct absolute path for wildcard pattern\n                                CONF_WILDCARD=${CONFIG_FILE%nginx.conf}${VALUE%;*}\n                            ;;\n                        esac\n                        for FOUND_CONF in ${CONF_WILDCARD}; do\n                            if [ \"${FOUND_CONF}\" = \"${CONF_WILDCARD}\" ]; then\n                                LogText \"Found no match for wildcard pattern: ${CONF_WILDCARD}\"\n                                break\n                            fi\n                            FOUND=0\n                            for CONF in ${NGINX_CONF_FILES}; do\n                                if [ \"${CONF}\" = \"${FOUND_CONF}\" ]; then FOUND=1; LogText \"Found this file already in our configuration files array, not adding to queue\"; fi\n                            done\n                            for CONF in ${NGINX_CONF_FILES_ADDITIONS}; do\n                                if [ \"${CONF}\" = \"${FOUND_CONF}\" ]; then FOUND=1; LogText \"Found this file already in our configuration files array (additions), not adding to queue\"; fi\n                            done\n                            if [ ${FOUND} -eq 0 ]; then NGINX_CONF_FILES_ADDITIONS=\"${NGINX_CONF_FILES_ADDITIONS} ${FOUND_CONF}\"; fi\n                        done\n                    else\n                        LogText \"Result: this include does not point to a file\"\n                    fi\n                ;;\n                index)\n                ;;\n                keepalive_timeout)\n                ;;\n                listen)\n                    NGINX_LISTEN_FOUND=1\n                    # Test for ssl on listen statement\n                    FIND_SSL=$(echo ${VALUE} | grep ssl)\n                    if [ ! \"${FIND_SSL}\" = \"\" ]; then NGINX_SSL_ON=1; fi\n                ;;\n                location)\n                    NGINX_LOCATION_FOUND=1\n                ;;\n                return)\n                    NGINX_RETURN_FOUND=1\n                ;;\n                root)\n                    NGINX_ROOT_FOUND=1\n                ;;\n                server_name)\n                ;;\n                ssl)\n                    if [ \"${VALUE}\" = \"on\" ]; then NGINX_SSL_ON=1; fi\n                ;;\n                ssl_certificate)\n                    LogText \"Found SSL certificate in nginx configuration\"\n                ;;\n                ssl_certificate_key)\n                ;;\n                ssl_ciphers)\n                    NGINX_SSL_CIPHERS=1\n                ;;\n                ssl_prefer_server_ciphers)\n                    if [ \"${VALUE}\" = \"on\" ]; then NGINX_SSL_PREFER_SERVER_CIPHERS=1; fi\n                ;;\n                ssl_protocols)\n                    NGINX_SSL_PROTOCOLS=1\n                    VALUE=$(echo ${VALUE} | sed 's/;$//' | tr '[:upper:]' '[:lower:]')\n                    for ITEM in ${VALUE}; do\n                        LogText \"Result: found protocol ${ITEM}\"\n                        case ${ITEM} in\n                            \"sslv2\" | \"sslv3\" | \"tlsv1\")\n                                NGINX_WEAK_SSL_PROTOCOL_FOUND=1\n                            ;;\n                        esac\n                        Report \"ssl_tls_protocol_enabled[]=${ITEM}\"\n                        ReportDetails --service nginx --field protocol --value \"${ITEM}\"\n                    done\n                ;;\n                ssl_session_cache)\n                ;;\n                ssl_session_timeout)\n                ;;\n                types)\n                ;;\n                *)\n                    LogText \"Found unknown option ${OPTION} in nginx configuration\"\n                ;;\n            esac\n            if [ ${STORE_SETTING} -eq 1 ]; then\n                CONFIG_TREE=\"${BREADCRUMB}\"\n                if [ -z \"${CONFIG_TREE}\" ]; then CONFIG_TREE=\"/\"; fi\n                if [ -z \"${OPTION}\" ]; then OPTION=\"NA\"; fi\n                if [ -z \"${VALUE}\" ]; then VALUE=\"NA\"; fi\n                StoreNginxSettings --config ${CONFIG_FILE} --tree ${CONFIG_TREE} --depth ${DEPTH} --setting ${OPTION} --value \"${VALUE}\"\n            fi\n        done\n    }\n\n\n    ################################################################################\n    # Name        : PortIsListening()\n    # Description : Check if machine is listening on specified protocol and port\n    #\n    # Parameters  : $1 = protocol\n    #               $2 = port\n    # Returns     : exit code (0 = listening, 1 = not listening, 255 = can't perform test)\n    # Usage       : if PortIsListening \"TCP\" 22; then echo \"Port is listening\"; fi\n    ################################################################################\n\n    PortIsListening() {\n        if [ -z \"${LSOFBINARY}\" ]; then\n            return 255\n        else\n            if [ $# -eq 2 ] && [ $1 = \"TCP\" -o $1 = \"UDP\" ]; then\n                LogText \"Test: find service listening on $1:$2\"\n                if [ $1 = \"TCP\" ]; then FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -i${1} -s${1}:LISTEN -P -n | grep \":${2} \"); else FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -i${1} -P -n | grep \":${2} \"); fi\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    LogText \"Result: found service listening on port $2 ($1)\"\n                    return 0\n                else\n                    LogText \"Result: did not find service listening on port $2 ($1)\"\n                    return 1\n                fi\n            else\n                return 255\n                ReportException ${TEST_NO} \"Error in function call to PortIsListening\"\n            fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : Progress()\n    # Description : Displays progress on screen with dots\n    #\n    # Parameters  : $1 = --finish or text (string)\n    # Returns     : <nothing>\n    # Tip         : Use this function from Register with the --progress parameter\n    ################################################################################\n\n    Progress() {\n        if [ ${CRONJOB} -eq 0 ]; then\n            if [ ${QUIET} -eq 0 ]; then\n                if [ \"$1\" = \"--finish\" ]; then\n                    ${ECHOCMD} \"\"\n                else\n                    # If the No-Break version of echo is known, use that (usually breaks in combination with -e)\n                    if [ ! \"${ECHONB}\" = \"\" ]; then\n                        ${ECHONB} \"$1\"\n                    else\n                        ${ECHOCMD} -en \"$1\"\n                    fi\n                fi\n            fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : RandomString()\n    # Description : Displays progress on screen with dots\n    #\n    # Parameters  : $1 = number (amount of characters, optional)\n    # Returns     : RANDOMSTRING variable\n    # Usage       : RandomString 32\n    ################################################################################\n\n    RandomString() {\n        # Check a (pseudo) random character device\n        if [ -c /dev/urandom ]; then FILE=\"/dev/urandom\"\n        elif [ -c /dev/random ]; then FILE=\"/dev/random\"\n        else\n          Display \"Can not use RandomString function, as there is no random device to be used\"\n        fi\n        if [ $# -eq 0 ]; then SIZE=16; else SIZE=$1; fi\n        CSIZE=$((SIZE / 2))\n        RANDOMSTRING=$(head -c ${CSIZE} /dev/urandom | od -An -x | tr -d ' ' | cut -c 1-${SIZE})\n    }\n\n\n    ################################################################################\n    # Name        : Readonly()\n    # Description : Mark a variable as read-only data\n    #\n    # Returns     : <nothing>\n    # Notes       : new function, not in use yet\n    ################################################################################\n\n    Readonly() {\n        if [ $# -eq 1 ]; then\n            if type -t typeset; then\n                typeset -r $1\n            else\n                Debug \"No typeset available to mark variable '$1' as read-only variable\"\n            fi\n        else\n            ExitFatal \"Expected 1 parameter, received none or multiple\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : Register()\n    # Description : Register a test and see if it has to be run\n    #\n    # Parameters  : multiple, see test\n    # Returns     : SKIPTEST (0 or 1)\n    ################################################################################\n\n    GetTimestamp() {\n        ts=0\n        # Detect if the implementation of date supports nanoseconds,\n        if [ \"${OS}\" = \"Linux\" ]; then\n            current_nanoseconds=$(date \"+%N\")\n            # Verify if the result of the command is a number\n            if [ -n \"$current_nanoseconds\" ] && [ \"$current_nanoseconds\" -eq \"$current_nanoseconds\" ] 2>/dev/null; then\n                ts=$(date \"+%s%N\")\n            else\n                ts=$(date \"+%s\")\n            fi\n        else\n            ts=$(date \"+%s\")\n        fi\n        echo $ts\n    }\n\n    Register() {\n        # Do not insert a log break, if previous test was not logged\n        if [ ${SKIPLOGTEST} -eq 0 ]; then LogTextBreak; fi\n        ROOT_ONLY=0; SKIPTEST=0; SKIPLOGTEST=0; SKIPREASON=\"\"; PREQS_MET=\"\"\n        TEST_CATEGORY=\"\"; TEST_NEED_NETWORK=\"\"; TEST_NEED_OS=\"\"; TEST_NEED_PKG_MGR=0; TEST_NEED_PLATFORM=\"\"\n        TOTAL_TESTS=$((TOTAL_TESTS + 1))\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --category)\n                    shift\n                    TEST_CATEGORY=$1\n                ;;\n                --description)\n                    shift\n                    TEST_DESCRIPTION=$1\n                ;;\n                --platform)\n                    shift\n                    TEST_NEED_PLATFORM=$1\n                ;;\n                --network)\n                    shift\n                    TEST_NEED_NETWORK=$1\n                ;;\n                --os)\n                    shift\n                    TEST_NEED_OS=$1\n                ;;\n                --package-manager-required)\n                    TEST_NEED_PKG_MGR=1\n                ;;\n                --preqs-met)\n                    shift\n                    PREQS_MET=$1\n                ;;\n                --progress)\n                    Progress \".\"\n                ;;\n                --root-only)\n                    shift\n                    if [ \"$1\" = \"YES\" -o \"$1\" = \"yes\" ]; then\n                        ROOT_ONLY=1\n                    elif [ \"$1\" = \"NO\" -o \"$1\" = \"no\" ]; then\n                        ROOT_ONLY=0\n                    else\n                        Debug \"Invalid option for --root-only parameter of Register function\"\n                    fi\n                ;;\n                --skip-reason)\n                    shift\n                    SKIPREASON=\"$1\"\n                ;;\n                --test-no)\n                    shift\n                    TEST_NO=$1\n                ;;\n                --weight)\n                    shift\n                    TEST_WEIGHT=$1\n                ;;\n\n                *)\n                    echo \"INVALID OPTION (Register): $1\"\n                    exit 1\n                ;;\n            esac\n            # Go to next parameter\n            shift\n        done\n\n        # Measure timing\n        CURRENT_TS=$(GetTimestamp)\n        if [ ${PREVIOUS_TS} -gt 0 ]; then\n            SLOW_TEST=0\n            TIME_THRESHOLD=$SLOW_TEST_THRESHOLD  # seconds\n\n            # Calculate timing and determine if we use seconds or nanoseconds (more precise)\n            TIME_DIFF=$((CURRENT_TS - PREVIOUS_TS))\n            if [ ${CURRENT_TS} -gt 1000000000000000000 ]; then\n                TIME_DIFF_FORMAT=\"nanoseconds\"\n                TIME_THRESHOLD=$((TIME_THRESHOLD * 1000000000))\n                if [ ${TIME_DIFF} -gt ${TIME_THRESHOLD} ]; then\n                    SLOW_TEST=1\n                    # Convert back to seconds for readability\n                    TIME_DIFF_FORMAT=\"seconds\"\n                    TIME_DIFF=$(echo ${TIME_DIFF} | ${AWKBINARY} '{printf \"%f\",$1/1000000000}')\n                fi\n            else\n                TIME_DIFF_FORMAT=\"seconds\"\n                if [ ${TIME_DIFF} -gt ${TIME_THRESHOLD} ]; then\n                    SLOW_TEST=1\n                fi\n            fi\n            if [ ${SLOW_TEST} -eq 1 ]; then\n                DisplayWarning \"Test ${PREVIOUS_TEST} had a long execution: ${TIME_DIFF} ${TIME_DIFF_FORMAT}\"\n                Report \"slow_test[]=${PREVIOUS_TEST},${TIME_DIFF}\"\n            fi\n        fi\n\n        # Skip test if it's configured in profile (old style)\n        if [ ${SKIPTEST} -eq 0 ]; then\n            FIND=$(echo \"${TEST_SKIP_ALWAYS}\" | grep \"${TEST_NO}\" | tr '[:lower:]' '[:upper:]')\n            if [ ! \"${FIND}\" = \"\" ]; then SKIPTEST=1; SKIPREASON=\"Skipped by configuration\"; fi\n        fi\n\n        # Check if this test is on the list to skip\n        if [ ${SKIPTEST} -eq 0 ]; then\n            VALUE=$(echo ${TEST_NO} | tr '[:lower:]' '[:upper:]')\n            for I in ${SKIP_TESTS}; do\n                if [ \"${I}\" = \"${VALUE}\" ]; then SKIPTEST=1; SKIPREASON=\"Skipped by profile setting (skip-test)\"; fi\n            done\n        fi\n\n        # Skip if test is not in the list\n        if [ ${SKIPTEST} -eq 0 -a ! \"${TESTS_TO_PERFORM}\" = \"\" ]; then\n            FIND=$(echo \"${TESTS_TO_PERFORM}\" | grep \"${TEST_NO}\")\n            if [ \"${FIND}\" = \"\" ]; then SKIPTEST=1; SKIPREASON=\"Test not in list of tests to perform\"; fi\n        fi\n\n        # Do not run scans which have a higher intensity than what we prefer\n        if [ ${SKIPTEST} -eq 0 -a \"${TEST_WEIGHT}\" = \"H\" -a \"${SCAN_TEST_HEAVY}\" = \"NO\" ]; then SKIPTEST=1; SKIPREASON=\"Test to system intensive for scan mode (H)\"; fi\n        if [ ${SKIPTEST} -eq 0 -a \"${TEST_WEIGHT}\" = \"M\" -a \"${SCAN_TEST_MEDIUM}\" = \"NO\" ]; then SKIPTEST=1; SKIPREASON=\"Test to system intensive for scan mode (M)\"; fi\n\n        # Test if our OS is the same as the requested OS (can be multiple values)\n        if [ ${SKIPTEST} -eq 0 -a -n \"${TEST_NEED_OS}\" ]; then\n            HASMATCH=0\n            for I in ${TEST_NEED_OS}; do\n                if [ \"${I}\" = \"${OS}\" ]; then HASMATCH=1; fi\n            done\n            if [ ${HASMATCH} -eq 0 ]; then\n                SKIPTEST=1; SKIPREASON=\"Incorrect guest OS (${TEST_NEED_OS} only)\"\n                if [ ${LOG_INCORRECT_OS} -eq 0 ]; then SKIPLOGTEST=1; fi\n            fi\n        fi\n\n        # Skip test when it belongs to another category (default is 'all')\n        if [ ${SKIPTEST} -eq 0 -a -n \"${TEST_CATEGORY_TO_CHECK}\" -a ! \"${TEST_CATEGORY_TO_CHECK}\" = \"all\" -a ! \"${TEST_CATEGORY}\" = \"${TEST_CATEGORY_TO_CHECK}\" ]; then\n            SKIPTEST=1; SKIPREASON=\"Incorrect category (${TEST_CATEGORY_TO_CHECK} only)\"\n        fi\n\n        # Check for correct hardware platform\n        if [ ${SKIPTEST} -eq 0 -a -n \"${TEST_NEED_PLATFORM}\" ]; then\n            HASMATCH=0\n            for I in ${TEST_NEED_PLATFORM}; do\n                if [ \"${I}\" = \"${HARDWARE}\" ]; then HASMATCH=1; fi\n            done\n            if [ ${HASMATCH} -eq 0 ]; then\n                SKIPTEST=1; SKIPREASON=\"Incorrect hardware platform (${TEST_NEED_PLATFORM} only)\"\n            fi\n        fi\n\n        # Check for required (and discovered) package manager\n        if [ ${SKIPTEST} -eq 0 -a ${TEST_NEED_PKG_MGR} -eq 1 -a ${HAS_PACKAGE_MANAGER} -eq 0 ]; then SKIPTEST=1; SKIPREASON=\"Requires a known package manager to test presence of a particular package\"; fi\n\n        # Not all prerequisites met, like missing tool\n        if [ ${SKIPTEST} -eq 0 -a \"${PREQS_MET}\" = \"NO\" ]; then SKIPTEST=1; if [ -z \"${SKIPREASON}\" ]; then SKIPREASON=\"Prerequisites not met (ie missing tool, other type of Linux distribution)\"; fi; fi\n\n        # Skip if a test is root only and we are running a non-privileged test\n        if [ ${SKIPTEST} -eq 0 -a ${ROOT_ONLY} -eq 1 -a ! ${MYID} = \"0\" ]; then\n            SKIPTEST=1; SKIPREASON=\"This test needs root permissions\"\n            SKIPPED_TESTS_ROOTONLY=\"${SKIPPED_TESTS_ROOTONLY}====${TEST_NO}:space:-:space:${TEST_DESCRIPTION}\"\n            #SkipTest \"${TEST_NO}:Test:space:requires:space:root:space:permissions:-:-:\"\n        fi\n\n        # Skip test?\n        if [ ${SKIPTEST} -eq 0 ]; then\n            # First wait X seconds (depending pause_between_tests)\n            if [ ${TEST_PAUSE_TIME} -gt 0 ]; then sleep ${TEST_PAUSE_TIME}; fi\n\n            # Increase counter for every registered test which is performed\n            CountTests\n            if [ ${SKIPLOGTEST} -eq 0 ]; then\n                LogText \"Performing test ID ${TEST_NO} (${TEST_DESCRIPTION})\"\n                if IsVerbose; then Debug \"Performing test ID ${TEST_NO} (${TEST_DESCRIPTION})\"; fi\n            fi\n            TESTS_EXECUTED=\"${TEST_NO}|${TESTS_EXECUTED}\"\n        else\n            if [ ${SKIPLOGTEST} -eq 0 ]; then LogText \"Skipped test ${TEST_NO} (${TEST_DESCRIPTION})\"; fi\n            if [ ${SKIPLOGTEST} -eq 0 ]; then LogText \"Reason to skip: ${SKIPREASON}\"; fi\n            TESTS_SKIPPED=\"${TEST_NO}|${TESTS_SKIPPED}\"\n        fi\n\n        # Save timestamp for next time the Register function is called\n        PREVIOUS_TEST=\"${TEST_NO}\"\n        PREVIOUS_TS=\"${CURRENT_TS}\"\n    }\n\n\n    ################################################################################\n    # Name        : RemoveColors()\n    # Description : Disabled colors by overriding them (defined in include/consts)\n    #\n    # Notes       : Can be activated using --no-colors\n    ################################################################################\n\n    RemoveColors() {\n        COLORS=0  # disable most color selections\n\n        # Normal color names\n        CYAN=\"\"\n        BLUE=\"\"\n        BROWN=\"\"\n        DARKGRAY=\"\"\n        GRAY=\"\"\n        GREEN=\"\"\n        LIGHTBLUE=\"\"\n        MAGENTA=\"\"\n        PURPLE=\"\"\n        RED=\"\"\n        YELLOW=\"\"\n        WHITE=\"\"\n\n        # Colors with background\n        BG_BLUE=\"\"\n        BG_WARNING=\"\"\n\n        # Semantic names\n        BAD=\"\"\n        BOLD=\"\"\n        HEADER=\"\"\n        NORMAL=\"\"\n        NOTICE=\"\"\n        OK=\"\"\n        WARNING=\"\"\n        SECTION=\"\"\n    }\n\n    ################################################################################\n    # Name        : RemovePIDFile()\n    # Description : When defined, remove the file storing the process ID\n    #\n    # Parameters  : <none>\n    # Returns     : <nothing>\n    ################################################################################\n\n    # Remove PID file\n    RemovePIDFile() {\n        # Test if PIDFILE is defined, before checking file presence\n        if [ -n \"${PIDFILE}\" ]; then\n            if [ -f \"${PIDFILE}\" ]; then\n                rm -f \"${PIDFILE}\"\n                LogText \"PID file removed (${PIDFILE})\"\n            else\n                LogText \"PID file not found (${PIDFILE})\"\n            fi\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : RemoveTempFiles()\n    # Description : When created, delete any temporary file\n    ################################################################################\n\n    # Remove any temporary files\n    RemoveTempFiles() {\n        if [ ! \"${TEMP_FILES}\" = \"\" ]; then\n            LogText \"Temporary files: ${TEMP_FILES}\"\n            # Clean up temp files\n            for FILE in ${TEMP_FILES}; do\n                # Temporary files should be in /tmp\n                TMPFILE=$(echo ${FILE} | grep -E \"^/tmp/lynis\" | grep -v \"\\.\\.\")\n                if [ -n \"${TMPFILE}\" ]; then\n                    if [ -f \"${TMPFILE}\" ]; then\n                        LogText \"Action: removing temporary file ${TMPFILE}\"\n                        rm -f \"${TMPFILE}\"\n                    else\n                        LogText \"Info: temporary file ${TMPFILE} was already removed\"\n                    fi\n                else\n                    LogText \"Found invalid temporary file (${FILE}), not removed. Check your /tmp directory.\"\n                fi\n            done\n        else\n            LogText \"No temporary files to be deleted\"\n        fi\n      }\n\n\n    ################################################################################\n    # Name        : Report()\n    # Description : Store data in the report file\n    #\n    # Parameters  : $1 = data (format: key=value)\n    # Returns     : <nothing>\n    ################################################################################\n\n    Report() {\n        if [ ${CREATE_REPORT_FILE} -eq 1 ]; then echo \"$1\" >> ${REPORTFILE}; fi\n    }\n\n\n    ################################################################################\n    # Name        : ReportDetails()\n    # Description : Adds specific details to the report, in particular when many\n    #               smaller atomic tests are performed. For example sysctl keys,\n    #               and SSH settings.\n    #\n    # Parameters  : <multiple fields, see test>\n    # Returns     : <nothing>\n    # Notes       : Need to check for values (strip out semicolons from values)\n    #               Only add fields which are filled in\n    ################################################################################\n\n    ReportDetails() {\n        TEST_DESCRIPTION=\"\"\n        TEST_FIELD=\"\"\n        TEST_ID=\"\"\n        TEST_OTHER=\"\"\n        TEST_PREFERRED_VALUE=\"\"\n        TEST_SERVICE=\"\"\n        TEST_VALUE=\"\"\n        while [ $# -ge 1 ]; do\n\n            case $1 in\n                --description)\n                    shift\n                    TEST_DESCRIPTION=\"desc:$1;\"\n                ;;\n                --field)\n                    shift\n                    TEST_FIELD=\"field:$1;\"\n                ;;\n                --preferredvalue|--preferred-value)\n                    shift\n                    TEST_PREFERRED_VALUE=\"prefval:$1;\"\n                ;;\n                # Other details\n                --other)\n                    shift\n                    TEST_OTHER=\"other:$1;\"\n                ;;\n                --service)\n                    shift\n                    TEST_SERVICE=\"$1\"\n                ;;\n                --test)\n                    shift\n                    TEST_ID=$1\n                ;;\n                --value)\n                    shift\n                    TEST_VALUE=\"value:$1;\"\n                ;;\n                *)\n                    echo \"INVALID OPTION (ReportDetails): $1\"\n                    ExitFatal\n                ;;\n            esac\n            shift # Go to next parameter\n        done\n        if [ \"${TEST_ID}\" = \"\" ]; then TEST_ID=\"-\"; fi\n        if [ \"${TEST_SERVICE}\" = \"\" ]; then TEST_SERVICE=\"-\"; fi\n        Report \"details[]=${TEST_ID}|${TEST_SERVICE}|${TEST_DESCRIPTION}${TEST_FIELD}${TEST_PREFERRED_VALUE}${TEST_VALUE}${TEST_OTHER}|\"\n    }\n\n\n    ################################################################################\n    # Name        : ReportException()\n    # Description : Store an exceptional event in the report\n    #\n    # Parameters  : $1 = test ID + colon + 2 numeric characters (TEST-1234:01)\n    #               $2 = string (text)\n    # Notes       : Allow this function with only 1 parameter in strict mode with ${2-Text}\n    ################################################################################\n\n    ReportException() {\n        Report \"exception_event[]=$1|${2-NoInfo}|\"\n        LogText \"Exception: test has an exceptional event ($1) with text ${2-NoText}\"\n        if [ ${QUIET} -eq 0 ]; then\n            DisplayException \"$1\" \"$2\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : ReportManual()\n    # Description : Add an item to the report that requires manual intervention\n    #\n    # Parameters  : $1 = string (text)\n    ################################################################################\n\n    ReportManual() {\n        Report \"manual_event[]=$1\"\n        LogText \"Manual: one or more manual actions are required for further testing of this control/plugin\"\n    }\n\n\n    ################################################################################\n    # Name        : ReportSuggestion()\n    # Description : Log a suggestion to the report file\n    #\n    # Parameters  : <ID> <Suggestion> <Details> <Solution>\n    #               $1 = Test ID - Lynis ID (use CUST-.... for your own tests)\n    #               $2 = Suggestion - Suggestion text to be displayed\n    #               $3 = Details - Specific item or details\n    #               $4 = Solution - Optional link for additional information:\n    #                    * url:https://example.org/how-to-solve-link\n    #                    * text:Additional explanation\n    #                    * - (dash) for none\n    # Returns     : <nothing>\n    ################################################################################\n\n    ReportSuggestion() {\n        TOTAL_SUGGESTIONS=$((TOTAL_SUGGESTIONS + 1))\n        if [ $# -eq 0 ]; then echo \"Not enough arguments provided for function ReportSuggestion\"; ExitFatal; fi\n        if [ $# -ge 1 ]; then TEST=\"$1\"; else TEST=\"UNKNOWN\"; fi\n        if [ $# -ge 2 ]; then MESSAGE=\"$2\"; else MESSAGE=\"UNKNOWN\"; fi\n        if [ $# -ge 3 ]; then DETAILS=\"$3\"; else DETAILS=\"-\"; fi\n        if [ $# -ge 4 ]; then SOLUTION=\"$4\"; else SOLUTION=\"-\"; fi\n        if [ $# -ge 5 ]; then echo \"Too many arguments for function ReportSuggestion\"; ExitFatal; fi\n        Report \"suggestion[]=${TEST}|${MESSAGE}|${DETAILS}|${SOLUTION}|\"\n        LogText \"Suggestion: ${MESSAGE} [test:${TEST}] [details:${DETAILS}] [solution:${SOLUTION}]\"\n    }\n\n\n    ################################################################################\n    # Name        : ReportWarning()\n    # Description : Log a warning to the report file\n    #\n    # Parameters  : $1 = test ID\n    #               $2 = message (optional)\n    #               $3 = details (optional)\n    #               $4 = possible solution (optional)\n    # Returns     : <nothing>\n    ################################################################################\n\n    ReportWarning() {\n        TOTAL_WARNINGS=$((TOTAL_WARNINGS + 1))\n        # Old style used L/M/H level as second parameter. This is deprecated as of 3.x\n        if [ \"$2\" = \"L\" -o \"$2\" = \"M\" -o \"$2\" = \"H\" ]; then\n            ExitFatal \"Deprecated usage of ReportWarning() function\"\n        else\n            # New style warning format:\n            # <ID> <Warning> <Details> <Solution>\n            #\n            # <ID>         Lynis ID (use CUST-.... for your own tests)\n            # <Warning>    Warning text to be displayed\n            # <Details>    Specific item or details\n            # <Solution>   Optional link for additional information:\n            #              * url:http://site/link\n            #              * text:Additional explanation\n            #              * - for none\n            if [ $# -eq 0 ]; then echo \"Not enough arguments provided for function ReportWarning\"; ExitFatal; fi\n            if [ $# -ge 1 ]; then TEST=\"$1\"; else TEST=\"UNKNOWN\"; fi\n            if [ $# -ge 2 ]; then MESSAGE=\"$2\"; else MESSAGE=\"UNKNOWN\"; fi\n            if [ $# -ge 3 ]; then DETAILS=\"$3\"; else DETAILS=\"-\"; fi\n            if [ $# -ge 4 ]; then SOLUTION=\"$4\"; else SOLUTION=\"-\"; fi\n            if [ $# -ge 5 ]; then echo \"Too many arguments for function ReportWarning\"; ExitFatal; fi\n        fi\n        Report \"warning[]=${TEST}|${MESSAGE}|${DETAILS}|${SOLUTION}|\"\n        LogText \"Warning: ${MESSAGE} [test:${TEST}] [details:${DETAILS}] [solution:${SOLUTION}]\"\n    }\n\n\n    ################################################################################\n    # Name        : SafeInput()\n    # Description : Test provided string to see if it contains unwanted characters\n    #\n    # Input       : string + optional class (parameter 2)\n    # Returns     : exit code (0 = input considered to be safe, 1 = validation failed)\n    ################################################################################\n\n    SafeInput() {\n        exitcode=1\n        # Test against the string with a generic test set\n        if [ $# -eq 1 ]; then\n            input=\"$1\"\n            # Use sed to strip all characters -except- those that are allowed\n            # - Common set of characters: a-z, A-Z, 0-9\n            # - Special characters: , /._-:=\n            # - Space for names (like auditor name)\n            cleaned=$(echo \"$input\" | sed 's/[^[:space:]a-zA-Z0-9\\/\\._:=-]//g')\n        # If two parameters are specified, then test input against specified class\n        elif [ $# -eq 2 ]; then\n            input=\"$1\"\n            testchars=\"$2\"\n            cleaned=$(echo $1 | tr -cd \"${testchars}\")\n        else\n            ExitFatal \"No argument or too many arguments provided to SafeInput()\"\n        fi\n        # Test if the cleaned string is the same as the original input\n        if [ \"${cleaned}\" = \"${input}\" ]; then\n            exitcode=0\n        fi\n        return ${exitcode}\n    }\n\n\n    ################################################################################\n    # Name        : SafeFile()\n    # Description : Check if a file is safe to use\n    #\n    # Parameters  : $1 = file name\n    # Returns     : exit code (0 = OK, 1 = issue)\n    ################################################################################\n\n    SafeFile() {\n        unsafe=0\n        if [ $# -ne 1 ]; then\n            ExitFatal \"No argument or too many arguments provided to SafeFile()\"\n        else\n            FILE=\"$1\"\n\n            # Generic checks\n            if [ -g \"${FILE}\" ]; then\n                LogText \"Security alert: file has setgid attribute\"\n                unsafe=1\n            # sticky bit\n            elif [ -k \"${FILE}\" ]; then\n                LogText \"Security alert: file has sticky bit\"\n                unsafe=1\n            # symbolic link\n            elif [ -L \"${FILE}\" ]; then\n                LogText \"Security alert: file is a symbolic link\"\n                unsafe=1\n            elif [ -f \"${FILE}\" ]; then\n                LogText \"Security check: file is normal\"\n            else\n                unsafe=1\n            fi\n\n            # Perform additional checks based on privilege level\n            if [ ${PRIVILEGED} -eq 0 ]; then\n                # File is not owned by active user, but still able to write\n                if [ ! -O \"${FILE}\" -a -w \"${FILE}\" ]; then\n                    unsafe=1\n                    LogText \"Security alert: file is not owned by active user, but can write to it\"\n                fi\n            fi\n\n            # Check file permissions\n            if ! SafePerms \"${FILE}\"; then\n                unsafe=1\n            fi\n\n        fi\n\n        return ${unsafe}\n    }\n\n\n    ################################################################################\n    # Name        : SafePerms()\n    # Description : Check if a file has safe permissions to be used\n    #\n    # Parameters  : $1 = file name\n    #               $2 = type of file (optional)\n    # Returns     : 0 (file permissions OK) or break\n    ################################################################################\n\n    SafePerms() {\n        exitcode=1\n        IS_PARAMETERS=0\n        IS_PROFILE=0\n\n        if [ ${IGNORE_FILE_PERMISSION_ISSUES} -eq 0 ]; then\n            PERMS_OK=0\n            LogText \"Checking permissions of $1\"\n\n            if [ $# -gt 0 ]; then\n\n                if [ $# -eq 2 ]; then\n                    case \"$2\" in\n                        \"parameters\")\n                            IS_PARAMETERS=1\n                        ;;\n                        \"profile\")\n                            IS_PROFILE=1\n                        ;;\n                    esac\n                else\n                    FIND=$(echo $1 | grep \"/parameters\")\n                    if [ $? -eq 0 ]; then IS_PARAMETERS=1; fi\n                fi\n                # Check file permissions\n                if [ ! -f \"$1\" ]; then\n                    LogText \"Fatal error: file $1 does not exist.\"\n                    ExitFatal \"Fatal error: file $1 does not exist\"\n                else\n                    PERMS=$(ls -l $1)\n\n                    # Owner permissions\n                    OWNER=$(echo ${PERMS} | awk -F\" \" '{ print $3 }')\n                    OWNERID=$(ls -n $1 | awk -F\" \" '{ print $3 }')\n                    if [ ${PENTESTINGMODE} -eq 0 -a ${IS_PARAMETERS} -eq 0 ]; then\n                        if [ ! \"${OWNER}\" = \"root\" -a ! \"${OWNERID}\" = \"0\" ]; then\n                            echo \"Fatal error: file $1 should be owned by user 'root' when running it as root (found: ${OWNER}).\"\n                            ExitFatal\n                        fi\n                    fi\n                    # Group permissions\n                    GROUP=$(echo ${PERMS} | awk -F\" \" '{ print $4 }')\n                    GROUPID=$(ls -n $1 | awk -F\" \" '{ print $4 }')\n\n                    if [ ${PENTESTINGMODE} -eq 0 -a ${IS_PARAMETERS} -eq 0 ]; then\n                        if [ ! \"${GROUP}\" = \"root\" -a ! \"${GROUP}\" = \"wheel\" -a ! \"${GROUPID}\" = \"0\" ]; then\n                            echo \"Fatal error: group owner of directory $1 should be owned by root group, wheel or similar (found: ${GROUP}).\"\n                            ExitFatal\n                        fi\n                    fi\n\n                    # Owner permissions\n                    OWNER_PERMS=$(echo ${PERMS} | cut -c2-4)\n                    if [ ! \"${OWNER_PERMS}\" = \"rw-\" -a ! \"${OWNER_PERMS}\" = \"r--\" ]; then\n                        echo \"Fatal error: permissions of file $1 are not strict enough. Access to 'owner' should be read-write, or read. Change with: chmod u=rw $1\"\n                        ExitFatal\n                    fi\n\n                    # Group permissions\n                    # TODO - harden this even more by setting default to read-only for group (like 'other')\n                    GROUP_PERMS=$(echo ${PERMS} | cut -c5-7)\n                    if [ ! \"${GROUP_PERMS}\" = \"rw-\" -a ! \"${GROUP_PERMS}\" = \"r--\" -a ! \"${GROUP_PERMS}\" = \"---\" ]; then\n                        echo \"Fatal error: permissions of file $1 are not strict enough. Access to 'group' should be read-write, read, or none. Change with: chmod g=r $1\"\n                        ExitFatal\n                    fi\n\n                    # Other permissions\n                    OTHER_PERMS=$(echo ${PERMS} | cut -c8-10)\n                    if [ ! \"${OTHER_PERMS}\" = \"---\" -a ! \"${OTHER_PERMS}\" = \"r--\" ]; then\n                        echo \"Fatal error: permissions of file $1 are not strict enough. Access to 'other' should be denied or read-only. Change with: chmod o=r $1\"\n                        ExitFatal\n                    fi\n                    # Set PERMS_OK to 1 if no fatal errors occurred\n                    PERMS_OK=1\n                    LogText \"File permissions are OK\"\n                    exitcode=0\n                fi\n            else\n                ReportException \"SafePerms()\" \"Invalid number of arguments for function\"\n            fi\n        else\n            PERMS_OK=1\n            exitcode=0\n        fi\n        return ${exitcode}\n\n    }\n\n\n    ################################################################################\n    # Name        : SearchItem()\n    # Description : Search if a specific string exists in in a file\n    #\n    # Parameters  : $1 = search key (string)\n    #               $2 = file (string)\n    #               $3 = optional arguments:\n    #                    --sensitive - don't store results in log\n    # Returns     : True (0) or False (1)\n    ################################################################################\n\n    SearchItem()  {\n        PERFORM_SCAN=0\n        MASK_LOG=0\n        RETVAL=1\n        if [ $# -lt 2 ]; then\n            ExitFatal \"Not enough arguments for function SearchItem()\"\n        elif [ $# -ge 2 ]; then\n            FILE=$2\n            STRING=$1\n            PERFORM_SCAN=1\n        fi\n\n        # Parse any additional arguments\n        if [ $# -gt 2 ]; then\n            shift; shift # Skip the first two (string and file)\n            while [ $# -ge 1 ]; do\n                case $1 in\n                    \"--sensitive\") MASK_LOG=1 ;;\n                esac\n                shift # Go to next parameter\n            done\n        fi\n\n        if [ ${PERFORM_SCAN} -eq 1 ]; then\n            # Don't search in /dev/null, it's too empty there\n            if [ -f ${FILE} ]; then\n                # Check if we can find the main type (with or without brackets)\n                LogText \"Test: search string ${STRING} in file ${FILE}\"\n                FIND=$(grep -E \"${STRING}\" ${FILE})\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found search string '${STRING}'\"\n                    if [ ${MASK_LOG} -eq 0 ]; then LogText \"Full string returned: ${FIND}\"; fi\n                    RETVAL=0\n                else\n                    LogText \"Result: search search string '${STRING}' NOT found\"\n                    RETVAL=1\n                fi\n            else\n                LogText \"Skipping search, file (${FILE}) does not exist\"\n                ReportException \"${TEST_NO}\" \"Test is trying to search for a string in nonexistent file\"\n            fi\n        else\n            ReportException \"${TEST_NO}\" \"Search test is skipped, which is unexpected\"\n        fi\n        return ${RETVAL}\n    }\n\n\n\n\n    ################################################################################\n    # Name        : ShowComplianceFinding()\n    # Description : Display a section of a compliance standard which is not fulfilled\n    #\n    # Parameters  : <several parameters, see test>\n    # Returns     : <nothing>\n    ################################################################################\n\n    ShowComplianceFinding() {\n        REASON=\"\"\n        STANDARD_NAME=\"\"\n        STANDARD_VERSION=\"\"\n        STANDARD_SECTION=\"\"\n        STANDARD_SECTION_TITLE=\"\"\n        ACTUAL_VALUE=\"\"\n        EXPECTED_VALUE=\"\"\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --standard)\n                    shift\n                    STANDARD_NAME=$1\n                ;;\n                --version)\n                    shift\n                    STANDARD_VERSION=$1\n                ;;\n                --section)\n                    shift\n                    STANDARD_SECTION=$1\n                ;;\n                --section-title)\n                    shift\n                    STANDARD_SECTION_TITLE=$1\n                ;;\n                --reason)\n                    shift\n                    REASON=$1\n                ;;\n                --actual)\n                    shift\n                    ACTUAL_VALUE=$1\n                ;;\n                --expected)\n                    shift\n                    EXPECTED_VALUE=$1\n                ;;\n\n                *)\n                    echo \"INVALID OPTION (ShowComplianceFinding): $1\"\n                    exit 1\n                ;;\n            esac\n            # Go to next parameter\n            shift\n        done\n        # Should we show this non-compliance on screen?\n        SHOW=0\n        case ${STANDARD_NAME} in\n            cis)\n                if [ ${COMPLIANCE_ENABLE_CIS} -eq 1 ]; then SHOW=1; fi\n                STANDARD_FRIENDLY_NAME=\"CIS\"\n            ;;\n            hipaa)\n                if [ ${COMPLIANCE_ENABLE_HIPAA} -eq 1 ]; then SHOW=1; fi\n                STANDARD_FRIENDLY_NAME=\"HIPAA\"\n            ;;\n            iso27001)\n                if [ ${COMPLIANCE_ENABLE_ISO27001} -eq 1 ]; then SHOW=1; fi\n                STANDARD_FRIENDLY_NAME=\"ISO27001\"\n            ;;\n            pci-dss)\n                if [ ${COMPLIANCE_ENABLE_PCI_DSS} -eq 1 ]; then SHOW=1; fi\n                STANDARD_FRIENDLY_NAME=\"PCI DSS\"\n            ;;\n        esac\n        # Only display if standard is enabled in the profile and mark system as non-compliant\n        if [ ${SHOW} -eq 1 ]; then\n            COMPLIANCE_FINDINGS_FOUND=1\n            DisplayManual \"  [${WHITE}${STANDARD_FRIENDLY_NAME} ${STANDARD_VERSION}${NORMAL}] - ${CYAN}Section ${STANDARD_SECTION}${NORMAL} - ${WHITE}${STANDARD_SECTION_TITLE}${NORMAL}\"\n            DisplayManual \"  - Details:        ${REASON}\"\n            DisplayManual \"  - Configuration:  ${RED}${ACTUAL_VALUE}${NORMAL} / ${EXPECTED_VALUE}\"\n            DisplayManual \"\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : ShowSymlinkPath()\n    # Description : Check if we can find the path behind a symlink\n    #\n    # Parameters  : $1 = file (string)\n    # Returns     : FOUNDPATH (0 not found, 1 found path), SYMLINK (new path)\n    ################################################################################\n\n    ShowSymlinkPath() {\n        if [ $# -eq 0 ]; then ExitFatal \"Function ShowSymlinkPath() called without a file name\"; fi\n        sFILE=$1\n        FOUNDPATH=0\n        SYMLINK_USE_PYTHON=0\n        SYMLINK_USE_READLINK=0\n        LogText \"Action: checking symlink for file ${sFILE}\"\n        # Check for symlink\n        if [ -L ${sFILE} ]; then\n\n            # macOS does not know -f option, nor do some others\n            if [ \"${OS}\" = \"macOS\" ]; then\n                # If a Python binary is found, use the one in path\n                if [ ${BINARY_SCAN_FINISHED} -eq 0 -a \"${PYTHONBINARY}\" = \"\" ]; then\n                    FIND=$(which python 2> /dev/null | grep -v \"no [^ ]* in \")\n                    if [ ! \"${FIND}\" = \"\" ]; then LogText \"Setting temporary pythonbinary variable\"; PYTHONBINARY=\"${FIND}\"; fi\n                fi\n\n                if [ ! \"${PYTHONBINARY}\" = \"\" ]; then\n                    SYMLINK_USE_PYTHON=1\n                    LogText \"Note: using Python to determine symlinks\"\n                    tFILE=$(python -c \"import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))\" $1)\n                fi\n            else\n                if [ ${BINARY_SCAN_FINISHED} -eq 0 -a \"${READLINKBINARY}\" = \"\" ]; then\n                    FIND=$(which readlink 2> /dev/null | grep -v \"no [^ ]* in \")\n                    if [ ! \"${FIND}\" = \"\" ]; then LogText \"Setting temporary readlinkbinary variable\"; READLINKBINARY=\"${FIND}\"; fi\n                fi\n\n                if [ ! \"${READLINKBINARY}\" = \"\" ]; then\n                    SYMLINK_USE_READLINK=1\n                    LogText \"Note: Using real readlink binary to determine symlink on ${sFILE}\"\n                    tFILE=$(${READLINKBINARY} -f ${sFILE})\n                    LogText \"Result: readlink shows ${tFILE} as output\"\n                fi\n            fi\n            # Check if we can find the file now\n            if [ \"${tFILE}\" = \"\" ]; then\n                LogText \"Result: command did not return any value\"\n            elif [ -f ${tFILE} ]; then\n                sFILE=\"${tFILE}\"\n                LogText \"Result: symlink found, pointing to file ${sFILE}\"\n                FOUNDPATH=1\n            elif [ -b ${tFILE} ]; then\n                sFILE=\"${tFILE}\"\n                LogText \"Result: symlink found, pointing to block device ${sFILE}\"\n                FOUNDPATH=1\n            elif [ -c ${tFILE} ]; then\n                sFILE=\"${tFILE}\"\n                LogText \"Result: symlink found, pointing to character device ${sFILE}\"\n                FOUNDPATH=1\n            elif [ -d ${tFILE} ]; then\n                sFILE=\"${tFILE}\"\n                LogText \"Result: symlink found, pointing to directory ${sFILE}\"\n                FOUNDPATH=1\n            else\n                # Check the full path of the symlink, strip the filename, copy the path and linked filename together\n                tDIR=$(echo ${sFILE} | awk '{match($1, \"^.*/\"); print substr($1, 1, RLENGTH-1)}')\n                tFILE=\"${tDIR}/${tFILE}\"\n                if [ -L ${tFILE} ]; then\n                    LogText \"Result: this symlink links to another symlink\"\n                    # Ensure that we use a second try with the right tool as well\n                    if [ ${SYMLINK_USE_PYTHON} -eq 1 ]; then\n                        tFILE=$(python -c \"import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))\" ${tFILE})\n                    elif [ ${SYMLINK_USE_READLINK} -eq 1 ]; then\n                        tFILE=$(${READLINKBINARY} -f ${tFILE})\n                    fi\n                    # Check if we now have a normal file\n                    if [ -f ${tFILE} ]; then\n                        sFILE=\"${tFILE}\"\n                        LogText \"Result: symlink finally found, seems to be file ${sFILE}\"\n                        FOUNDPATH=1\n                    elif [ -d ${tFILE} ]; then\n                        sFILE=\"${tFILE}\"\n                        LogText \"Result: symlink finally found, seems to be directory ${sFILE}\"\n                        FOUNDPATH=1\n                    else\n                       LogText \"Result: could not find file ${tFILE}, most likely too complicated symlink or too often linked\"\n                    fi\n                elif [ -f ${tFILE} ]; then\n                    sFILE=\"${tFILE}\"\n                    LogText \"Result: symlink found, seems to be file ${sFILE}\"\n                    FOUNDPATH=1\n                elif [ -d ${tFILE} ]; then\n                    sFILE=\"${tFILE}\"\n                    LogText \"Result: symlink found, seems to be directory ${sFILE}\"\n                    FOUNDPATH=1\n                else\n                    LogText \"Result: file ${tFILE} in ${tDIR} not found\"\n                fi\n            fi\n        else\n            LogText \"Result: file ${sFILE} is not a symlink\"\n        fi\n        # Now check if our new location is actually a file or directory destination\n        if [ -L ${sFILE} ]; then\n            LogText \"Result: unable to determine symlink, or location ${sFILE} is just another symlink\"\n            FOUNDPATH=0\n        fi\n        if [ ${FOUNDPATH} -eq 1 ]; then\n            SYMLINK=\"${sFILE}\"\n        else\n            SYMLINK=\"\"\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : SkipAtomicTest()\n    # Description : Test if an atomic test should be skipped\n    #\n    # Input       : String (particular test)\n    # Returns     : 0 (skip test) or 1 (do not skip test)\n    # Usage       : if SkipAtomicTest \"ssh-7408:port\"; then echo \"Skip this atomic test\"; fi\n    ################################################################################\n\n    SkipAtomicTest() {\n        RETVAL=255\n        if [ $# -eq 1 ]; then\n            STRING=\"\"\n            RETVAL=1\n            # Check if this test is on the list to skip\n            for item in ${SKIP_TESTS}; do\n                STRING=$(echo $1 | tr '[:lower:]' '[:upper:]')\n                if [ \"${item}\" = \"${STRING}\" ]; then RETVAL=0; LogText \"Atomic test ($1) skipped by configuration (skip-test)\"; fi\n            done\n        else\n            ReportException \"SkipAtomicTest()\" \"Function called without right number of arguments (1)\"\n        fi\n        return $RETVAL\n    }\n\n\n    ################################################################################\n    # Name        : Status()\n    # Description : Reports back the status of tool\n    #\n    # Returns     : text to screen\n    # Notes       : kill --signal USR1 <PID> or pkill --signal USR1 lynis\n    ################################################################################\n\n    Status() {\n        echo \"\"\n        echo \"Date / time : $(date \"+%Y-%m-%d %H:%M:%S\")\"\n        echo \"Active test : ${TEST_NO:-NONE}\"\n        echo \"\"\n    }\n\n\n    ################################################################################\n    # Name        : StoreNginxSettings()\n    # Description : Store parsed settings from nginx (by ParseNginx)\n    # Input       : multiple options\n    # Returns     : <nothing>\n    ################################################################################\n\n    StoreNginxSettings() {\n        CONFIG_DEPTH=0; CONFIG_FILE=\"\"; CONFIG_SETTING=\"\"; CONFIG_TREE=\"\"; CONFIG_VALUE=\"\"\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --config)\n                    shift\n                    CONFIG_FILE=$1\n                ;;\n                --depth)\n                    shift\n                    CONFIG_DEPTH=$1\n                ;;\n                # none | events | server | unknown\n                --tree)\n                    shift\n                    CONFIG_TREE=$1\n                    case ${CONFIG_TREE} in\n                        \"/\") CONFIG_COUNTER=0 ;;\n                        \"/events\") CONFIG_COUNTER=${NGINX_EVENTS_COUNTER=0} ;;\n                        \"/http\") CONFIG_COUNTER=${NGINX_HTTP_COUNTER=0} ;;\n                        \"/server\") CONFIG_COUNTER=${NGINX_SERVER_COUNTER=0} ;;\n                        \"/server/location\") CONFIG_COUNTER=${NGINX_LOCATION_COUNTER=0} ;;\n                        *)\n                        Debug \"Unknown configuration tree of nginx ${CONFIG_TREE}\"\n                        ;;\n                    esac\n                ;;\n                --setting)\n                    shift\n                    CONFIG_SETTING=$1\n                ;;\n                --value)\n                    shift\n                    CONFIG_VALUE=$1\n                ;;\n                *)\n                    echo \"INVALID OPTION (StoreNginxSettings): $1 $2\"\n                    #ExitFatal\n                ;;\n            esac\n            # Go to next parameter\n            shift\n        done\n        if [ -z \"${CONFIG_DEPTH}\" ]; then CONFIG_DEPTH=\"0\"; fi\n        if [ -z \"${CONFIG_SETTING}\" ]; then CONFIG_SETTING=\"NA\"; fi\n        if [ -z \"${CONFIG_TREE}\" ]; then CONFIG_TREE=\"/\"; fi\n        if [ -z \"${CONFIG_VALUE}\" ]; then CONFIG_VALUE=\"NA\"; fi\n        Report \"nginx_config[]=|file=${CONFIG_FILE}|depth=${CONFIG_DEPTH}|tree=${CONFIG_TREE}|number=${CONFIG_COUNTER}|setting=${CONFIG_SETTING}|value=${CONFIG_VALUE}|\"\n    }\n\n\n    ################################################################################\n    # Name        : TestValue()\n    # Description : Test if a value is good/bad (e.g. according to best practices)\n    #\n    # Input       : --function <value> --value <value> --search <value>\n    # Returns     : 0 (True) or 1 (False)\n    # Usage       : if TestValue --function contains --value \"Full Text\" --search \"Text\"; then echo \"Found!\"; fi\n    ################################################################################\n\n    TestValue() {\n        RETVAL=255\n        FIND=\"\"\n        VALUE=\"\"\n        RESULT=\"\"\n        SEARCH=\"\"\n        CMP1=\"\"; CMP2=\"\"\n        while [ $# -ge 1 ]; do\n            case $1 in\n                --function)\n                    shift\n                    FUNCTION=$1\n                ;;\n                --value)\n                    shift\n                    VALUE=$1\n                ;;\n                --search)\n                    shift\n                    SEARCH=$1\n                ;;\n                *)\n                    echo \"INVALID OPTION USED (TestValue): $1\"\n                    exit 1\n                ;;\n            esac\n            # Go to next parameter\n            shift\n        done\n\n        if [ \"${VALUE}\" = \"\" ]; then echo \"No value provided to function (TestValue)\"; fi\n\n        # Apply the related function\n        case ${FUNCTION} in\n              \"contains\")\n                  FIND=$(echo ${VALUE} | grep -E \"${SEARCH}\")\n                  if [ \"${FIND}\" = \"\" ]; then RETVAL=1; else RETVAL=0; fi\n              ;;\n              #\"gt\" | \"greater-than\")   COLOR=$GREEN   ;;\n              \"equals\")\n                  CMP1=$(echo ${SEARCH} | tr '[:upper:]' '[:lower:'])\n                  CMP2=$(echo ${VALUE} | tr '[:upper:]' '[:lower:'])\n                  if [ \"${CMP1}\" = \"${CMP2}\" ]; then RETVAL=0; else RETVAL=1; fi\n              ;;\n              #\"not-equal\")   COLOR=$WHITE   ;;\n              #\"lt\" | \"less-than\")  COLOR=$YELLOW  ;;\n              *) echo \"INVALID OPTION USED (TestValue, parameter of function: $1)\"; exit 1 ;;\n        esac\n\n        if [ \"${RETVAL}\" -lt 2 ]; then\n            return ${RESULT}\n        else\n            Fatal \"ERROR: No result returned from function (TestValue). Incorrect usage?\"\n            #ExitFatal\n        fi\n    }\n\n\n    ################################################################################\n    # Name        : ViewCategories()\n    # Description : Show all available categories\n    #\n    # Input       : <nothing>\n    # Returns     : <nothing>\n    # Usage       : ViewCategories\n    ################################################################################\n\n    ViewCategories() {\n        for CATEGORY in ${TEST_AVAILABLE_CATEGORIES}; do echo \"${CATEGORY}\"; done\n        ExitClean\n    }\n\n\n    ################################################################################\n    # Name        : ViewGroups()\n    # Description : Show what group of tests are available\n    #\n    # Input       : <nothing>\n    # Returns     : <nothing>\n    # Usage       : ViewGroups\n    ################################################################################\n\n    ViewGroups() {\n        if [ -n \"${INCLUDEDIR}\" ]; then\n            for I in $(ls ${INCLUDEDIR}/tests_* | xargs -n 1 basename | sed 's/tests_//' | grep -v \"custom.template\"); do\n              echo \"${I}\"\n            done\n        fi\n        ExitClean\n    }\n\n\n    ################################################################################\n    # Name        : WaitForKeyPress()\n    # Description : Wait for the user to press [ENTER], unless quickmode is set\n    #\n    # Input       : <nothing>\n    # Returns     : <nothing>\n    # Usage       : WaitForKeyPress\n    ################################################################################\n\n    WaitForKeyPress() {\n        if [ ${QUICKMODE} -eq 0 ]; then\n            echo \"\"; echo \"[ Press [ENTER] to continue, or [CTRL]+C to stop ]\"\n            read -r void\n        fi\n    }\n\n\n    ################################################################################\n    #\n    # Legacy functions - Do not use!\n    #\n    ################################################################################\n    # For compatibility reasons they are listed here, but will be phased out in\n    # steps. If they still get used, they will trigger errors on screen.\n    ################################################################################\n\n    counttests() {\n        DisplayWarning \"Deprecated function used (counttests)\"\n        if IsDeveloperMode; then Debug \"Warning: old counttests function is used. Please replace any reference with CountTests.\"; fi\n        CountTests\n    }\n\n     logtext() {\n        DisplayWarning \"Deprecated function used (logtext)\"\n        if IsDeveloperMode; then Debug \"Warning: old logtext function is used. Please replace any reference with LogText.\"; fi\n        LogText \"$1\"\n    }\n\n     logtextbreak() {\n        DisplayWarning \"Deprecated function used (logtextbreak)\"\n        if IsDeveloperMode; then Debug \"Warning: old logtextbreak function is used. Please replace any reference with LogTextBreak.\"; fi\n        LogTextBreak \"$1\"\n    }\n\n     report() {\n        DisplayWarning \"Deprecated function used (report)\"\n        if IsDeveloperMode; then Debug \"Warning: old report function is used. Please replace any reference with Report.\"; fi\n        Report \"$1\"\n    }\n\n     wait_for_keypress() {\n        DisplayWarning \"Deprecated function used (wait_for_keypress)\"\n        if IsDeveloperMode; then Debug \"Warning: old wait_for_keypress function is used. Please replace any reference with WaitForKeyPress.\"; fi\n        WaitForKeyPress\n    }\n\n     ShowResult() {\n        DisplayWarning \"Deprecated function used (ShowResult)\"\n        if IsDeveloperMode; then Debug \"Warning: old ShowResult() function is used. Please replace any reference with WaitForKeyPress.\"; fi\n    }\n\n# EOF\n"
  },
  {
    "path": "include/helper_audit_dockerfile",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n\nif [ $# -eq 0 ]; then\n    Display --indent 2 --text \"${RED}Error: ${WHITE}Provide a file${NORMAL}\"\n    Display --text \" \"; Display --text \" \"\n    ExitFatal\nelse\n    FILE=$(echo $1 | grep -E \"^http|https\")\n    if HasData \"${FILE}\"; then\n        echo \"Provide a file (not a URL)\"\n        ExitFatal\n    else\n        if [ -f $1 ]; then\n            AUDIT_FILE=\"$1\"\n        else\n            Display --indent 2 --text \"File $1 does not exist\"\n            ExitFatal\n        fi\n    fi\n    Display --indent 2 --text \"File to audit = ${AUDIT_FILE}\"\nfi\n\n#####################################################\n\n#\n##################################################################################################\n#\n\n    InsertSection \"${SECTION_IMAGE}\"\n\n    PKGMGR=\"\"\n    FIND=$(grep \"^FROM\" ${AUDIT_FILE} | sed 's/ /:space:/g')\n    for I in ${FIND}; do\n        IMAGE=$(echo ${I} | sed 's/:space:/ /g' | awk '{ if ($1==\"FROM\") { print $2 }}')\n        TAG=$(echo ${IMAGE} | cut -d':' -f2)\n        Display --indent 2 --text \"Found image:\" --result \"${IMAGE}\"\n\n        IS_DEBIAN=$(echo ${IMAGE} | grep -i debian)\n        IS_FEDORA=$(echo ${IMAGE} | grep -i fedora)\n        IS_UBUNTU=$(echo ${IMAGE} | grep -i ubuntu)\n        IS_ALPINE=$(echo ${IMAGE} | grep -i alpine)\n        IS_LATEST=$(echo ${TAG} | grep -i latest)\n\n        if [ -n \"${IS_DEBIAN}\" ]; then IMAGE=\"debian\"; fi\n        if [ -n \"${IS_FEDORA}\" ]; then IMAGE=\"fedora\"; fi\n        if [ -n \"${IS_UBUNTU}\" ]; then IMAGE=\"ubuntu\"; fi\n        if [ -n \"${IS_ALPINE}\" ]; then IMAGE=\"alpine\"; fi\n        if [ -n \"${IS_LATEST}\" ]; then\n            ReportWarning \"dockerfile\" \"latest TAG used. Specifying a targeted OS image and version is better for reproducible results.\"\n        fi\n\n        case ${IMAGE} in\n            \"debian\")\n                LogText \"Image = Debian based\"\n                PKGMGR=\"apt\"\n                ;;\n            \"fedora*\")\n                LogText \"  Image = Fedora based\"\n                PKGMGR=\"yum\"\n                ;;\n            \"ubuntu\")\n                LogText \"  Image = Ubuntu based\"\n                PKGMGR=\"apt\"\n                ;;\n            \"alpine\")\n                LogText \"  Image = Alpine based\"\n                PKGMGR=\"apk\"\n                ;;\n            *)\n                Display --indent 2 --text \"Unknown image\" --result \"\" --color YELLOW\n                ;;\n        esac\n    done\n\n#\n##################################################################################################\n#\n    InsertSection \"${SECTION_BASICS}\"\n\n    MAINTAINER=$(grep -E -i \"*MAINTAINER\" ${AUDIT_FILE} | sed 's/=/ /g' | cut -d'\"' -f 2)\n    if [ -z \"${MAINTAINER}\" ]; then\n        ReportWarning \"dockerfile\" \"No maintainer found. Unclear who created this file.\"\n    else\n        Display --indent 2 --text \"Maintainer\" --result \"${MAINTAINER}\"\n    fi\n\n    ENTRYPOINT=$(grep \"^ENTRYPOINT\" ${AUDIT_FILE} | cut -d' ' -f2 )\n    if [ -z \"${ENTRYPOINT}\" ]; then\n        ReportWarning \"dockerfile\" \"No ENTRYPOINT defined in Dockerfile.\"\n    else\n        Display --indent 2 --text \"ENTRYPOINT\" --result \"${ENTRYPOINT}\"\n    fi\n\n    FIND=$(grep \"^CMD\" ${AUDIT_FILE} | cut -d' ' -f2 )\n    if [ -z \"${FIND}\" ]; then\n        ReportWarning \"dockerfile\" \"No CMD defines in Dockerfile.\"\n    else\n        CMD=$(echo ${FIND})\n        Display --indent 2 --text \"CMD\" --result \"${CMD}\"\n    fi\n\n    FIND=$(grep \"^USER\" ${AUDIT_FILE} | cut -d' ' -f2 )\n    if [ -z \"${FIND}\" ]; then\n        ReportWarning \"dockerfile\" \"No user declared in Dockerfile. Container will execute command as root\"\n    else\n        USER=$(echo ${FIND})\n        Display --indent 2 --text \"User\" --result \"${USER}\"\n    fi\n#\n##################################################################################################\n#\n    InsertSection \"${SECTION_SOFTWARE}\"\n\n    case $PKGMGR in\n    \"apt\")\n        FIND=$(grep -E \"apt-get(.*) install\" ${AUDIT_FILE})\n        if [ ! \"${FIND}\" = \"\" ]; then\n            LogText \"Found installation via apt-get\"\n        else\n            LogText \"No installations found via apt-get\"\n        fi\n        ;;\n     \"apk\")\n        FIND=$(grep -E \"apk(.*) add\" ${AUDIT_FILE})\n        if [ ! \"${FIND}\" = \"\" ]; then\n            LogText \"Found installation via apk\"\n        else\n            LogText \"No installations found via apk\"\n        fi\n        ;;\n    *)\n        LogText \"Unknown package manager\"\n    ;;\n    esac\n\n    FIND=$(grep -E \" (gcc|libc6-dev|make)\" ${AUDIT_FILE} | grep -v \"^#\")\n    if [ ! \"${FIND}\" = \"\" ]; then\n        ReportWarning \"dockerfile\" \"Possible development utilities found, which is not advised for production environment\"\n        LogText \"Details: ${FIND}\"\n    fi\n\n    # SSH\n    FIND_OPENSSH=$(grep openssh ${AUDIT_FILE})\n    if [ ! \"${FIND_OPENSSH}\" = \"\" ]; then\n        Display --indent 2 --text \"OpenSSH\" --result \"FOUND\" --color RED\n        ReportSuggestion \"dockerfile\" \"Don't use OpenSSH in container, use 'docker exec' instead\"\n    fi\n#\n##################################################################################################\n#\n    InsertSection \"${SECTION_DOWNLOADS}\"\n\n    FILE_DOWNLOAD=0\n\n    LogText \"Checking usage of cURL\"\n    FIND_CURL=$(grep curl ${AUDIT_FILE})\n    if [ ! \"${FIND_CURL}\" = \"\" ]; then\n        Display --indent 4 --text \"Download tool\" --result \"curl\"\n        FILE_DOWNLOAD=1\n    fi\n\n    LogText \"Checking usage of wget\"\n    FIND_WGET=$(grep wget ${AUDIT_FILE})\n    if HasData \"${FIND_WGET}\"; then\n        Display --indent 4 --text \"Download tool\" --result \"wget\"\n        FILE_DOWNLOAD=1\n    fi\n\n\n    FIND=$(grep \"^ADD http\" ${AUDIT_FILE})\n    if HasData \"${FIND}\"; then\n        FILE_DOWNLOAD=1\n        ReportWarning \"dockerfile\" \"Found download of file via ADD. Unclear if the integrity of this file is checked, or file is signed\"\n        LogText \"Details: ${FIND}\"\n    fi\n\n    if [ ${FILE_DOWNLOAD} -eq 1 ]; then\n\n        SSL_USED_FIND=$(grep -E \"(https)\" ${AUDIT_FILE})\n\n        if HasData \"${SSL_USED_FIND}\"; then\n            SSL_USED=\"YES\"\n            COLOR=\"GREEN\"\n        else\n            SSL_USED=\"NO\"\n            COLOR=\"RED\"\n            ReportSuggestion \"Use SSL downloads when possible to increase security (DNSSEC, HTTPS, validation of domain, avoid MitM)\"\n        fi\n        Display --indent 2 --text \"Integrity testing performed\" --result \"${SSL_USED}\" --color ${COLOR}\n        HASHING_USED=$(grep -E \"(sha1sum|sha256sum|sha512sum)\" ${AUDIT_FILE})\n        Display --indent 2 --text \"Hashing\" --result \"${HASHING_USED}\"\n        KEYS_USED=$(grep -E \"(apt-key adv)\" ${AUDIT_FILE}| sed 's/RUN apt-key adv//g'| sed 's/--keyserver/Key Server:/g' | sed 's/--recv/Key Value:/g')\n        Display --indent 2 --text \"Signing keys used\" --result \"${KEYS_USED}\"\n        Display --indent 2 --text \"All downloads properly checked\" --result \"?\"\n    else\n        Display --indent 2 --text \"No files seems to be downloaded in this Dockerfile\"\n\n    fi\n#\n##################################################################################################\n#\n    InsertSection \"${SECTION_PERMISSIONS}\"\n\n    FIND=$(grep -i \"chmod 777\" ${AUDIT_FILE})\n    if HasData \"${FIND}\"; then\n        ReportWarning \"dockerfile\" \"Warning: chmod 777 found\"\n    fi\n#\n##################################################################################################\n#\n\n    # Removing temp file\n    LogText \"Action: Removing temporary file ${TMP_FILE}\"\n    if [ -f ${TMP_FILE} ]; then\n        rm -f ${TMP_FILE}\n    fi\n\n# EOF\n"
  },
  {
    "path": "include/helper_configure",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n######################################################################\n#\n# Helper program to configure Lynis\n#\n######################################################################\n#\n# How to use:\n# ------------\n#\n# Run:\n#   lynis configure settings quick\n#   lynis configure settings quick=yes:debug=yes\n#\n######################################################################\n\n    CONFIGURE_CRONJOB=0\n    CONFIGURE_SETTINGS=0\n\n    # Check configure mode\n    if [ \"${HELPER_PARAMS}\" = \"\" ]; then\n        ${ECHOCMD} \"${YELLOW}Provide one or more configuration settings${NORMAL}\"\n        ${ECHOCMD} \"\"\n        ${ECHOCMD} \"Examples:\"\n        ${ECHOCMD} \"  $0 configure cronjob\"\n        ${ECHOCMD} \"\"\n        ${ECHOCMD} \"  $0 configure settings quick\"\n        ${ECHOCMD} \"  $0 configure settings debug:developer-mode:quick\"\n        ${ECHOCMD} \"  $0 configure settings debug=yes:developer-mode=no:quick=yes\"\n        ${ECHOCMD} \"\"\n        ExitClean\n    elif [ \"$1\" = \"cronjob\" ]; then\n        CONFIGURE_CRONJOB=1\n    elif [ \"$1\" = \"settings\" ]; then\n        CONFIGURE_SETTINGS=1\n    fi\n\n\n    # Perform activities depending on requested task\n    if [ ${CONFIGURE_CRONJOB} -eq 1 ]; then\n\n        ${ECHOCMD} \"Automatic configuration for cronjobs is not implemented yet.\"\n        ExitClean\n\n    elif [ ${CONFIGURE_SETTINGS} -eq 1 ]; then\n\n        # Determine where profiles are stored\n        if [ -z \"${PROFILEDIR}\" ]; then\n            ${ECHOCMD} \"Can not configure Lynis, as profile directory is unknown\"\n            ExitFatal\n        fi\n        if [ -z \"${CUSTOM_PROFILE}\" ]; then\n            ${ECHOCMD} \"No custom profile found yet.\"\n            ${ECHOCMD} \"Suggestion: create one with 'touch custom.prf' or 'touch /etc/lynis/custom.prf'\"\n            ExitFatal\n        fi\n\n        CONFIGURE_SETTINGS=$(echo $2 | sed 's/:/ /g')\n        for I in ${CONFIGURE_SETTINGS}; do\n            SETTING=$(echo ${I} | awk -F= '{print $1}')\n            VALUE=$(echo ${I} | awk -F= '{print $2}')\n            if [ \"${VALUE}\" = \"\" ]; then\n                ${ECHOCMD} \"Profile:          ${CUSTOM_PROFILE}\"\n                Debug \"Did not find a value configured on the command line for setting ${SETTING}\"\n                #read VALUE\n                else\n                  Debug \"Setting '${SETTING}' should be configured with value '${VALUE}'\"\n                  FIND=$(grep \"^${SETTING}\" ${CUSTOM_PROFILE})\n                  if [ \"${FIND}\" = \"\" ]; then\n                      ${ECHOCMD} \"Configuring setting '${CYAN}${SETTING}${NORMAL}'\"\n                      echo \"${SETTING}=${VALUE}\" >> ${CUSTOM_PROFILE}\n                      if [ $? -eq 0 ]; then ${ECHOCMD} \"${GREEN}Setting changed${NORMAL}\"; fi\n                    else\n                      ${ECHOCMD} \"${YELLOW}Notice${NORMAL}: Setting '${CYAN}${SETTING}${NORMAL}' was already configured (not changed)${NORMAL}\"\n                      ${ECHOCMD} \"        Current value: ${WHITE}${FIND}${NORMAL}\"\n                      ${ECHOCMD} \"\"\n                  fi\n            fi\n            # Now check if value is in line with expected type (boolean, integer, string)\n            # =To be implemented=\n        done\n        ${ECHOCMD} \"\"\n        ${ECHOCMD} \"\"\n        ExitClean\n\n    fi\n\n    ExitClean\n\n# EOF\n"
  },
  {
    "path": "include/helper_generate",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n######################################################################\n#\n# Helper program to generate specific details such as host IDs\n#\n######################################################################\n#\n# How to use:\n# ------------\n# Run: lynis generate <option>\n#\n######################################################################\n\nSAVEFILE=0\nGENERATE_ARGS=\"hostids systemd-units\"\n\nif [ $# -gt 0 ]; then\n    case $1 in\n        \"hostids\")\n\n            if [ $# -gt 1 ]; then\n                shift\n                if [ $1 = \"--save\" ]; then\n                    SAVEFILE=1\n                fi\n            fi\n\n            # Generate random host IDs\n            case \"${OS}\" in\n                \"AIX\")\n                    # hexdump does not exist on AIX\n                    HOSTID=$(head -c20 < /dev/urandom | xxd -c 20 -p)\n                    HOSTID2=$(head -c32 < /dev/urandom | xxd -c 32 -p)\n                ;;\n                *)\n                    # xxd does not exist on FreeBSD\n                    # Note: hexdump may omit leading or trailing zeroes.\n                    # Take 100 characters as input, turn to hex, then take first 40/64.\n                    HOSTID=$(head -c100 < /dev/urandom | hexdump -ve '\"%.2x\"' | head -c40)\n                    HOSTID2=$(head -c100 < /dev/urandom | hexdump -ve '\"%.2x\"' | head -c64)\n                ;;\n            esac\n\n            ${ECHOCMD} \"Generated host identifiers\"\n            ${ECHOCMD} \"- hostid: ${HOSTID}\"\n            ${ECHOCMD} \"- hostid2: ${HOSTID2}\"\n\n            if [ ${SAVEFILE} -eq 1 ]; then\n                FILE=\"${ROOTDIR}etc/lynis/hostids\"\n                if [ -f ${FILE} ]; then\n                    ${ECHOCMD} \"Error: hostids file already exists (${FILE})\"\n                    ${ECHOCMD} \"Remove the file first and rerun command\"\n                    ExitFatal\n                else\n                    OUTPUT=$(touch ${FILE} 2> /dev/null)\n                    if [ $? -eq 0 ]; then\n                        ${ECHOCMD} \"Created hostids file (${FILE})\"\n                        echo \"# generated using 'lynis generate hostids --save'\" > ${FILE}\n                        echo \"hostid=${HOSTID}\" >> ${FILE}\n                        echo \"hostid2=${HOSTID2}\" >> ${FILE}\n                    else\n                        ExitFatal \"Error: could not created hostids file (${FILE}). Issue with permissions?\"\n                    fi\n                fi\n            fi\n\n            ExitClean\n            ;;\n\n        \"cronjob\")\n            ${ECHOCMD} \"Not implemented yet\"\n            ;;\n\n        \"systemd-units\")\n\n            ${ECHOCMD} \"\"\n\n            ${ECHOCMD} \"${BG_BLUE}Step 1: create service unit (/etc/systemd/system/lynis.service)${NORMAL}\"\n\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"#\"\n            ${ECHOCMD} \"# Lynis service file for systemd\"\n            ${ECHOCMD} \"#\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"# Do not remove, so Lynis can provide a hint when a newer unit is available\"\n            ${ECHOCMD} \"# Generator=lynis\"\n            ${ECHOCMD} \"# Version=1\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Unit]\"\n            ${ECHOCMD} \"Description=Security audit and vulnerability scanner\"\n            ${ECHOCMD} \"Documentation=https://cisofy.com/docs/\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Service]\"\n            ${ECHOCMD} \"Nice=19\"\n            ${ECHOCMD} \"IOSchedulingClass=best-effort\"\n            ${ECHOCMD} \"IOSchedulingPriority=7\"\n            ${ECHOCMD} \"Type=simple\"\n            MYBINARY=$(which lynis 2>/dev/null)\n            MOREOPTIONS=\"\"\n            if [ -n \"${LICENSE_KEY}\" ]; then\n                MOREOPTIONS=\" --upload\"\n            fi\n            ${ECHOCMD} \"ExecStart=${MYBINARY:-/path/to/lynis} audit system --cronjob${MOREOPTIONS}\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Install]\"\n            ${ECHOCMD} \"WantedBy=multi-user.target\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"\"\n\n            ${ECHOCMD} \"${BG_BLUE}Step 2: create timer unit (/etc/systemd/system/lynis.timer)${NORMAL}\"\n            ${ECHOCMD} \"\"\n\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"#\"\n            ${ECHOCMD} \"# Lynis timer file for systemd\"\n            ${ECHOCMD} \"#\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"# Do not remove, so Lynis can provide a hint when a newer unit is available\"\n            ${ECHOCMD} \"# Generator=lynis\"\n            ${ECHOCMD} \"# Version=1\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Unit]\"\n            ${ECHOCMD} \"Description=Daily timer for the Lynis security audit and vulnerability scanner\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Timer]\"\n            ${ECHOCMD} \"OnCalendar=daily\"\n            ${ECHOCMD} \"RandomizedDelaySec=1800\"\n            ${ECHOCMD} \"Persistent=false\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Install]\"\n            ${ECHOCMD} \"WantedBy=timers.target\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"#################################################################################\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"\"\n\n            ${ECHOCMD} \"${BG_BLUE}Step 3 - Enable the timer${NORMAL}\"\n\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"Tell systemd you made changes: systemctl daemon-reload\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"Enable and start the timer (so no reboot is needed): systemctl enable --now lynis.timer\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"${BG_BLUE}Optional - Customize${NORMAL}\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"Want to override the timer? Run: systemctl edit lynis.timer\"\n            ${ECHOCMD} \"Note: set the timer by first resetting it, then set the preferred value\"\n            ${ECHOCMD} \"\"\n            ${ECHOCMD} \"[Timer]\"\n            ${ECHOCMD} \"OnCalendar=\"\n            ${ECHOCMD} \"OnCalendar=*-*-* 03:00:00\"\n            ${ECHOCMD} \"\"\n            ;;\n        *)                      ${ECHOCMD} \"Unknown argument '${RED}$1${NORMAL}' for lynis generate\" ;;\n    esac\nelse\n    ${ECHOCMD} \"\\n  ${WHITE}Provide an additional argument${NORMAL}\\n\\n\"\n    for ITEM in ${GENERATE_ARGS}; do\n        ${ECHOCMD} \"    lynis generate ${BROWN}${ITEM}${NORMAL}\"\n    done\n    ${ECHOCMD} \"\\n\"\n    ${ECHOCMD} \"\"\n    ${ECHOCMD} \"Extended help about the generate command can be provided with: $0 show commands generate\"\nfi\n\n\nExitClean\n\n# EOF\n"
  },
  {
    "path": "include/helper_show",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n######################################################################\n#\n# Helper program to share details\n#\n######################################################################\n#\n# How to use:\n# ------------\n# Run: lynis show <option>\n#\n######################################################################\n\nCOMMANDS=\"audit configure generate show update upload-only\"\nHELPERS=\"audit configure show update\"\nOPTIONS=\"--auditor\\n--cronjob (--cron)\\n--debug\\n--developer\\n--devops\\n--forensics\\n--help (-h)\\n--log-file\\n--manpage (--man)\\n--no-colors\\n--no-log\\n--no-plugins\\n--pentest\\n--profile\\n--plugin-dir\\n--quick (-Q)\\n--quiet (-q)\\n--report-file\\n--reverse-colors\\n--tests\\n--tests-from-category\\n--tests-from-group\\n--usecwd\\n--upload\\n--verbose\\n--version (-V)\\n--wait\\n--warnings-only\"\n\nSHOW_ARGS=\"categories changelog commands dbdir details environment eol groups help hostids includedir language license logfile man options os pidfile plugindir profiles release releasedate report settings tests version workdir\"\nSHOW_HELP=\"lynis show ${BROWN}categories${NORMAL}              (display test categories)\nlynis show ${BROWN}changelog${NORMAL} ${GRAY}[version]${NORMAL}     (release details)\nlynis show ${BROWN}commands${NORMAL}                (all available commands)\nlynis show ${BROWN}dbdir${NORMAL}                   (database directory)\nlynis show ${BROWN}details${NORMAL}                 (display test details from log file)\nlynis show ${BROWN}environment${NORMAL}             (hardware, virtual machine, or container type)\nlynis show ${BROWN}eol${NORMAL}                     (OS end-of-life status)\nlynis show ${BROWN}groups${NORMAL}                  (test groups)\nlynis show ${BROWN}help${NORMAL}                    (detailed information about arguments)\nlynis show ${BROWN}hostids${NORMAL}                 (unique IDs for this system)\nlynis show ${BROWN}includedir${NORMAL}              (include directory for tests and functions)\nlynis show ${BROWN}language${NORMAL}                (configured or detected language)\nlynis show ${BROWN}license${NORMAL}                 (license details)\nlynis show ${BROWN}logfile${NORMAL}                 (location of logfile)\nlynis show ${BROWN}man${NORMAL}                     (show help)\nlynis show ${BROWN}options${NORMAL}                 (available flags and options)\nlynis show ${BROWN}os${NORMAL}                      (operating system and version)\nlynis show ${BROWN}pidfile${NORMAL}                 (active file to stored process ID)\nlynis show ${BROWN}plugindir${NORMAL}               (directory with plugins)\nlynis show ${BROWN}profiles${NORMAL}                (discovered profiles)\nlynis show ${BROWN}release${NORMAL}                 (version)\nlynis show ${BROWN}releasedate${NORMAL}             (date of release)\nlynis show ${BROWN}report${NORMAL}                  (location of report data)\nlynis show ${BROWN}settings${NORMAL}                (display configured settings, ${WHITE}options:${NORMAL} ${CYAN}--brief --nocolors${NORMAL})\nlynis show ${BROWN}tests${NORMAL} ${GRAY}[test]${NORMAL}            (display information about one or more tests)\nlynis show ${BROWN}tests skipped${NORMAL}           (which tests to skip according profile)\nlynis show ${BROWN}version${NORMAL}                 (${PROGRAM_NAME} version)\nlynis show ${BROWN}workdir${NORMAL}                 (work directory)\"\n\nAUDIT_ARGS=\"( dockerfile | system )\"\nAUDIT_HELP=\"\n  ${WHITE}lynis audit <target>${NORMAL}\n\n  ${CYAN}audit dockerfile ${BROWN}<file>${NORMAL}\n\n  Perform security audit on a Docker build file\n  ${GRAY}Example:${NORMAL}\n    lynis audit dockerfile Dockerfile\n\n\n  ${CYAN}audit system ${GRAY}[options]${NORMAL}\n\n  Perform security system audit\n\n  ${GRAY}Examples:${NORMAL}\n    lynis audit system\n    lynis audit system --cronjob\n    lynis audit system --profile developer.prf\n    lynis audit system --quick\n\n\n  ${CYAN}audit system remote ${BROWN}<target> ${GRAY}[options]${NORMAL}\n\n  Perform security system audit on a remote target\n\n  ${GRAY}Examples:${NORMAL}\n    lynis audit system remote 192.168.1.100\n    lynis audit system remote 192.168.1.100 --no-colors\n\n\"\n\nGENERATE_ARGS=\"( --save )\"\nGENERATE_HELP=\"\n  Generate random value for hostid and hostid2\n  ${WHITE}lynis generate hostids${NORMAL}\n\n  Generate and save values\n  ${WHITE}lynis generate hostids --save${NORMAL}\n\n  Generate systemd units to run Lynis on a schedule (e.g. daily)\n  ${WHITE}lynis generate systemd-units${NORMAL}\n\n\"\n\n\nUPDATE_ARGS=\"check | info\"\nUPDATE_HELP=\"\n  ${CYAN}update info${NORMAL}\n\n  Check and show version information\n\n  ${CYAN}update check${NORMAL}\n\n  Just check if version is up-to-date\n\n\"\n\nUPLOAD_ONLY_HELP=\"\n  ${CYAN}update-only${NORMAL}\n\n  Perform just a data upload\n\n\"\n\nSHOW_SETTINGS_ARGS=\"--brief --configured-only --nocolors\"\nSHOW_TESTS_ARGS=\"skipped\"\n\nCOMMANDS_AUDIT_SYSTEM_USAGE=\"Usage: lynis audit system\"\nCOMMANDS_AUDIT_SYSTEM_FUNCTION=\"Function: performs a security audit of the system\"\n\nif [ $# -gt 0 ]; then\n    case $1 in\n        \"categories\")\n            ViewCategories\n            ;;\n        \"changelog\")\n            # Allow providing a version\n            if [ $# -gt 1 ]; then\n                shift; SEARCH_VERSION=\"$1\"\n            fi\n            PROGRAM_NAME_LOWER=$( echo ${PROGRAM_NAME} | tr '[:upper:]' '[:lower:]')\n            CHANGELOG_PATHS=\"/usr/share/doc/${PROGRAM_NAME} /usr/share/doc/${PROGRAM_NAME}-${PROGRAM_VERSION} /usr/share/doc/${PROGRAM_NAME_LOWER} .\"\n            CHANGELOG=\"\"\n            if [ -z \"${SEARCH_VERSION}\" ]; then SEARCH_VERSION=\"${PROGRAM_VERSION}\"; fi\n            STARTED=0\n            for FILEPATH in ${CHANGELOG_PATHS}; do\n                if [ -f ${FILEPATH}/CHANGELOG.md ]; then\n                    CHANGELOG=\"${FILEPATH}/CHANGELOG.md\"\n                # Check also for gzipped changelog\n                elif [ -f ${FILEPATH}/changelog.gz ]; then\n                    ZCAT=$(which zcat 2> /dev/null | grep -v \"no [^ ]* in \")\n                    if [ -n \"${ZCAT}\" ]; then\n                        CreateTempFile\n                        CHANGELOG=\"${TEMP_FILE}\"\n                        LogText \"Result: found gzipped changelog in ${FILEPATH}\"\n                        LogText \"Action: Creating temporary file to store text\"\n                        ${ZCAT} ${FILEPATH}/changelog.gz > ${CHANGELOG}\n                    else\n                        DisplayError \"Could not find zcat utility to use on gzipped changelog\"\n                    fi\n                fi\n                if [ -n \"${CHANGELOG}\" ]; then LogText \"Result: found changelog file: ${CHANGELOG}\"; break; fi\n            done\n            if [ -n \"${CHANGELOG}\" ]; then\n                SEARCH=$(sed 's/^## //' ${CHANGELOG} | grep -E \"^${PROGRAM_NAME} ${SEARCH_VERSION}\")\n                if [ $? -eq 0 ]; then\n                    while read -r LINE; do\n                        if [ ${STARTED} -eq 0 ]; then\n                            SEARCH=$(echo ${LINE} | sed 's/^## //' | grep -E \"^${PROGRAM_NAME} ${SEARCH_VERSION}\")\n                            if [ $? -eq 0 ]; then STARTED=1; ${ECHOCMD} \"${BOLD}${LINE}${NORMAL}\"; fi\n                        else\n                            # Stop if we find the next Lynis version\n                            SEARCH=$(echo ${LINE} | sed 's/^## //' | grep -E \"^${PROGRAM_NAME} [0-9]\\.[0-9]\\.[0-9]\")\n                            if [ $? -eq 0 ]; then\n                                break\n                            else\n                                ${ECHOCMD} \"${LINE}\"\n                            fi\n                        fi\n                    done < ${CHANGELOG}\n                else\n                    DisplayError \"Could not find this version in the changelog\"\n                    ${ECHOCMD} \"\"\n                    ${ECHOCMD} \"${HEADER}Usage:${NORMAL}\"\n                    ${ECHOCMD} \"$0 lynis show changelog [version]\"\n                    ${ECHOCMD} \"\"\n                    ${ECHOCMD} \"${HEADER}${PROGRAM_NAME} versions:${NORMAL}\"\n                    SEARCH=$(sed 's/^## //' ${CHANGELOG} | grep -E \"^Lynis [0-9]\\.[0-9]\\.[0-9] \" | awk '{print $2}' | sort -n)\n                    ${ECHOCMD} ${SEARCH}\n                    ExitFatal\n                fi\n            else\n                DisplayError \"Could not find the changelog file (searched in ${CHANGELOG_PATHS})\"\n                ExitFatal\n            fi\n            ;;\n        \"commands\")\n            if [ $# -eq 1 ]; then\n                ${ECHOCMD} \"\\n${WHITE}Commands:${NORMAL}\"\n                for ITEM in ${COMMANDS}; do\n                    ${ECHOCMD} \"lynis ${CYAN}${ITEM}${NORMAL}\"\n                done\n                ${ECHOCMD} \"\"\n            else\n                shift\n                if [ $# -eq 1 ]; then\n                    case $1 in\n                        \"audit\") ${ECHOCMD} \"${AUDIT_HELP}\" ;;\n                        \"configure\") ${ECHOCMD} \"No help available yet\" ;;\n                        \"generate\") ${ECHOCMD} \"${GENERATE_HELP}\" ;;\n                        \"show\") ${ECHOCMD} \"${SHOW_HELP}\" ;;\n                        \"update\")  ${ECHOCMD} \"${UPDATE_HELP}\" ;;\n                        \"upload-only\") ${ECHOCMD} \"${UPLOAD_ONLY_HELP}\" ;;\n                        *) DisplayError \"Unknown argument for 'commands'\"\n                    esac\n                else\n                    shift\n                    case $1 in\n                        \"dockerfile\")\n                            ${ECHOCMD} \"Usage: lynis audit dockerfile <file>\"\n                        ;;\n                        \"system\")\n                            ${ECHOCMD} \"${COMMANDS_AUDIT_SYSTEM_USAGE}\\n${COMMANDS_AUDIT_SYSTEM_FUNCTION}\\n\"\n                        ;;\n                        *)\n                            DisplayError \"Unknown argument '$1' for commands\"\n                        ;;\n                    esac\n                fi\n            fi\n            ;;\n        \"dbdir\")\n            ${ECHOCMD} \"${DBDIR}\"\n            ;;\n        \"details\")\n            if [ -z \"${LOGFILE}\" ]; then DisplayError \"Could not find log file to parse\"; fi\n            if [ $# -eq 1 ]; then\n                DisplayError \"This command needs a test ID (e.g. CORE-1000) to search for. This command is used after a scan (lynis audit system). Run 'lynis show tests' to see all available tests.\"\n            else\n                shift\n                if [ $# -eq 1 ]; then\n                    TESTID=\"$1\"\n                    awk -v search=\"Performing test ID $TESTID\" '$0 ~ search {++f;p=1}p&&f==1;/====/{p=0}' ${LOGFILE}\n                fi\n            fi\n            ;;\n        \"environment\")\n            if [ -z \"${CONTAINER_TYPE}\" ]; then\n                ${ECHOCMD} \"container=0\"\n            else\n                ${ECHOCMD} \"container=1\"\n                ${ECHOCMD} \"container-type=${CONTAINER_TYPE}\"\n            fi\n            if [ ${ISVIRTUALMACHINE} -eq 1 ]; then\n                ${ECHOCMD} \"virtual-machine=1\"\n                ${ECHOCMD} \"virtual-machine-type=${VMTYPE}\"\n            else\n                ${ECHOCMD} \"hardware=1\"\n                ${ECHOCMD} \"virtual-machine=0\"\n            fi\n            ;;\n        \"eol\")\n            ${ECHOCMD} \"Operating-system=${OS_FULLNAME}\"\n            if [ ${EOL} -eq 0 ]; then\n                ${ECHOCMD} \"End-of-life=No\"\n            elif [ ${EOL} -eq 1 ]; then\n                ${ECHOCMD} \"End-of-life=Yes\"\n            elif [ ${EOL} -eq 255 ]; then\n                ${ECHOCMD} \"End-of-life=Not tested\"\n            else\n                ${ECHOCMD} \"End-of-life=Unknown\"\n            fi\n            ;;\n        \"groups\")\n            ViewGroups\n            ;;\n        \"help\" | \"--help\" | \"-h\")\n            if [ $# -eq 1 ]; then\n                ${ECHOCMD} \"${PROGRAM_NAME} ${PROGRAM_VERSION} - Help\"\n                ${ECHOCMD} \"==========================\"\n                ${ECHOCMD} \"\"\n                ${ECHOCMD} \"${WHITE}Commands${NORMAL}:\"\n                for ITEM in ${COMMANDS}; do\n                    ${ECHOCMD} \"${CYAN}${ITEM}${NORMAL}\"\n                done\n                ${ECHOCMD} \"\"\n                ${ECHOCMD} \"Use 'lynis show help ${CYAN}<command>${NORMAL}' to see details\"\n                ${ECHOCMD} \"\"; ${ECHOCMD} \"\"\n                ${ECHOCMD} \"${WHITE}Options${NORMAL}:\\n${GRAY}${OPTIONS}${NORMAL}\"\n            else\n                shift\n                case $1 in\n                   \"audit\") ${ECHOCMD} \"${AUDIT_HELP}\" ;;\n                   \"configure\") ${ECHOCMD} \"No help available yet\" ;;\n                   \"generate\") ${ECHOCMD} \"${GENERATE_HELP}\" ;;\n                   \"show\") ${ECHOCMD} \"${SHOW_HELP}\" ;;\n                   \"update\") ${ECHOCMD} \"${UPDATE_HELP}\" ;;\n                   \"upload-only\") ${ECHOCMD} \"${UPLOAD_ONLY_HELP}\" ;;\n                   \"?\") ${ECHOCMD} \"${SHOW_ARGS}\" ;;\n                   *) ${ECHOCMD} \"Unknown argument provided for lynis show help\" ;;\n                esac\n            fi\n            ;;\n        \"helpers\")              for ITEM in ${HELPERS}; do ${ECHOCMD} ${ITEM}; done ;;\n        \"hostids\" | \"hostid\")\n            ${ECHOCMD} \"hostid=${HOSTID}\"\n            ${ECHOCMD} \"hostid2=${HOSTID2}\"\n            ${ECHOCMD} \"machineid=${MACHINEID}\"\n            ;;\n        \"includedir\")\n            ${ECHOCMD} \"${INCLUDEDIR}\"\n            ;;\n        \"language\")             ${ECHOCMD} \"${LANGUAGE}\" ;;\n        \"license\")              ${ECHOCMD} \"${PROGRAM_LICENSE}\" ;;\n        \"logfile\")              ${ECHOCMD} \"${LOGFILE}\" ;;\n        \"man\")                  ${ECHOCMD} \"Use ./lynis --man or man lynis\" ;;\n        \"options\")              ${ECHOCMD} \"${OPTIONS}\" ;;\n        \"os\")\n                                ${ECHOCMD} \"OS=${OS}\"\n                                ${ECHOCMD} \"OS_NAME=${OS_NAME}\"\n                                ${ECHOCMD} \"OS_FULLNAME=${OS_FULLNAME}\"\n                                ${ECHOCMD} \"OS_VERSION=${OS_VERSION}\"\n        ;;\n        \"pidfile\")              ${ECHOCMD} \"${PIDFILE}\" ;;\n        \"profile\" | \"profiles\") for ITEM in ${PROFILES}; do ${ECHOCMD} ${ITEM}; done ;;\n        \"profiledir\")           ${ECHOCMD} \"${PROFILEDIR}\" ;;\n        \"plugindir\")            ${ECHOCMD} \"${PLUGINDIR}\" ;;\n        \"release\")              ${ECHOCMD} \"${PROGRAM_VERSION}-${PROGRAM_RELEASE_TYPE}\" ;;\n        \"releasedate\")          ${ECHOCMD} \"${PROGRAM_RELEASE_DATE}\" ;;\n        \"report\")               ${ECHOCMD} \"${REPORTFILE}\" ;;\n        \"settings\")\n            BRIEF_OUTPUT=0\n            COLORED_OUTPUT=1\n            CONFIGURED_ONLY_OUTPUT=0\n            while [ $# -gt 1 ]; do\n                shift\n                case $1 in\n                   \"--brief\" | \"--br\") BRIEF_OUTPUT=1 ;;\n                   \"--configured-only\" | \"--co\") CONFIGURED_ONLY_OUTPUT=1 ;;\n                   \"--nocolors\" | \"--no-colors\" | \"--nc\") COLORED_OUTPUT=0; COLORS=0 ;;\n                   *)\n                       ${ECHOCMD} \"${RED}Error${NORMAL}: Invalid argument provided to 'lynis show settings'\\n\\n\"\n                       ${ECHOCMD} \"Suggestions:\"\n                       for ITEM in ${SHOW_SETTINGS_ARGS}; do ${ECHOCMD} \"lynis show settings ${ITEM}\"; done\n                       ExitFatal\n                   ;;\n                esac\n            done\n            if [ ${COLORED_OUTPUT} -eq 0 ]; then RemoveColors; fi\n            # Sort all settings and display them\n            SETTINGS=$(sort ${SETTINGS_FILE} | sed 's/ /:space:/g')\n            for LINE in ${SETTINGS}; do\n                SETTING=$(echo ${LINE} | awk -F';' '{print $1}')\n                VALUE=$(echo ${LINE} | awk -F';' '{print $2}')\n                DESCRIPTION=$(echo ${LINE} | awk -F';' '{print $3}' | sed 's/:space:/ /g')\n                if [ -z \"${VALUE}\" -a ${CONFIGURED_ONLY_OUTPUT} -eq 0 ]; then VALUE=\"${GRAY}[not configured]${NORMAL}\"; fi\n                if [ -n \"${VALUE}\" ]; then\n                    if [ ${BRIEF_OUTPUT} -eq 0 ]; then ${ECHOCMD} \"${GRAY}# ${DESCRIPTION}${NORMAL}\"; fi\n                    ${ECHOCMD} \"${WHITE}${SETTING}${NORMAL}=${CYAN}${VALUE}${NORMAL}\"\n                    if [ ${BRIEF_OUTPUT} -eq 0 ]; then ${ECHOCMD} \"\"; fi\n                fi\n            done\n            if [ ${BRIEF_OUTPUT} -eq 0 -a ${CONFIGURED_ONLY_OUTPUT} -eq 0 -a ${COLORED_OUTPUT} -eq 1 ]; then\n                if [ ${COLORS} -eq 1 ]; then\n                    ${ECHOCMD} \"# Add --brief to hide descriptions, --configured-only to show configured items only, or --nocolors to remove colors\"\n                else\n                    ${ECHOCMD} \"# Add --brief to hide descriptions, --configured-only to show configured items only\"\n                fi\n            fi\n\n            ;;\n        \"tests\")\n            if [ $# -gt 1 ]; then\n                shift\n                case $1 in\n                    \"skipped\")\n                        if [ -z \"${SKIP_TESTS}\" ]; then\n                            ${ECHOCMD} \"# ${CYAN}No tests are skipped (according profile)${NORMAL}\"\n                        else\n                            ${ECHOCMD} \"# Skipped tests (according profile)\"\n                            ${ECHOCMD} \"${SKIP_TESTS}\"\n                        fi\n                    ;;\n                    *)\n                        if [ -f ${DBDIR}/tests.db ]; then\n                            SEARCH=\"$1\"\n                            FIND=$(grep \"^${SEARCH}\" ${DBDIR}/tests.db | sed \"s/ /:space:/g\")\n                            if [ -z \"${FIND}\" ]; then\n                                ${ECHOCMD} \"${WARNING}Error${NORMAL}: ${BOLD}Could not find this test in the database${NORMAL}\\n\\n\"\n                                ExitFatal\n                            else\n                                for ITEM in ${FIND}; do\n                                    TEST_DESCRIPTION=$(echo ${ITEM} | sed \"s/:space:/ /g\" | awk -F: '{print $6}')\n                                    TEST=$(echo ${ITEM} | awk -F: '{print $1}')\n                                    TEST_TYPE=$(echo ${ITEM} | awk -F: '{print $2}')\n                                    TEST_CATEGORY=$(echo ${ITEM} | awk -F: '{print $3}')\n                                    TEST_GROUP=$(echo ${ITEM} | awk -F: '{print $4}')\n                                    TEST_OS=$(echo ${ITEM} | awk -F: '{print $5}')\n                                    TEST_SKIPPED=0\n                                    ${ECHOCMD} \"${CYAN}${TEST}${NORMAL}\"\n                                    ${ECHOCMD} \"===================================\"\n                                    ${ECHOCMD} \"\"\n                                    ${ECHOCMD} \"${WHITE}Type:${NORMAL} ${TEST_TYPE}\"\n                                    ${ECHOCMD} \"\"\n                                    ${ECHOCMD} \"${WHITE}Description:${NORMAL}\"\n                                    ${ECHOCMD} \"${TEST_DESCRIPTION}\"\n                                    ${ECHOCMD} \"\"\n                                    ${ECHOCMD} \"${WHITE}Category:${NORMAL} ${TEST_CATEGORY}, ${WHITE}Group:${NORMAL} ${TEST_GROUP}\"\n                                    ${ECHOCMD} \"\"\n                                    ${ECHOCMD} \"${WHITE}Test Execution:${NORMAL}\"\n                                    if [ \"${TEST_OS}\" = \"\" ]; then\n                                        ${ECHOCMD} \"  Operating System:    ${GREEN}Yes${NORMAL} (all systems)\"\n                                    elif [ \"${TEST_OS}\" = \"${OS}\" ]; then\n                                        ${ECHOCMD} \"  Operating System:    ${GREEN}Yes${NORMAL} (${TEST_OS} only)\"\n                                    else\n                                        ${ECHOCMD} \"  Operating System:    ${RED}No${NORMAL} (${TEST_OS} only)\"\n                                        TEST_SKIPPED=1\n                                    fi\n                                    if [ -z \"${SKIP_TESTS}\" ]; then\n                                        ${ECHOCMD} \"  Profile:             ${GREEN}Yes${NORMAL} (not configured)\"\n                                    else\n                                        FIND=$(echo ${SKIP_TESTS} | grep -E \"${TEST}\")\n                                        if [ -z \"${FIND}\" ]; then\n                                            ${ECHOCMD} \"  Profile:             ${GREEN}Yes${NORMAL} (test not marked to be skipped)\"\n                                        else\n                                            ${ECHOCMD} \"  Profile:             ${RED}No${NORMAL} (marked test as to be skipped)\"\n                                            TEST_SKIPPED=1\n                                        fi\n                                    fi\n                                    if [ ${TEST_SKIPPED} -eq 1 ]; then ${ECHOCMD} \"\"; ${ECHOCMD} \"  This test will NOT be performed on this system\"; fi\n\n                                    ${ECHOCMD} \"\"\n                                    ${ECHOCMD} \"\"\n\n                                done\n                            fi\n                        else\n                            ShowError \"Can not find tests database\"\n                            ${ECHOCMD} \"The changelog might not be installed on your system. Details can be found at ${PROGRAM_SOURCE}.\"\n                            ExitFatal\n                        fi\n                    ;;\n                esac\n            else\n                if [ -f ${DBDIR}/tests.db ]; then\n                    ${ECHOCMD} \"# Test       OS         Description\"\n                    ${ECHOCMD} \"# ======================================================================================\"\n                    awk -F: '{ if ($1 !~ /^#/) printf(\"%-10s %-10s %s (%s)\\n\",$1,$5,$6,$3)}' ${DBDIR}/tests.db\n                else\n                    ShowError \"Can not find tests database\"\n                    ${ECHOCMD} \"The changelog might not be installed on your system. Details can be found at ${PROGRAM_SOURCE}.\"\n                    ExitFatal\n                fi\n            fi\n            ;;\n        \"version\")              ${ECHOCMD} \"${PROGRAM_VERSION}\" ;;\n        \"workdir\")              ${ECHOCMD} \"${WORKDIR}\" ;;\n        \"?\")                    ${ECHOCMD} \"${SHOW_ARGS}\" ;;\n        *)                      ${ECHOCMD} \"Unknown argument '${RED}$1${NORMAL}' for lynis show\" ;;\n    esac\nelse\n    ${ECHOCMD} \"\\n  ${WHITE}Provide an additional argument${NORMAL}\\n\\n\"\n    for ITEM in ${SHOW_ARGS}; do\n        ${ECHOCMD} \"    lynis show ${BROWN}${ITEM}${NORMAL}\"\n    done\n    ${ECHOCMD} \"\\n\"\n    ${ECHOCMD} \"\"\n    ${ECHOCMD} \"Extended help about the show command can be provided with: $0 show commands show\"\nfi\n\n\nExitClean\n\n# More additions:\n# - categories\n# - workdir\n\n# EOF\n"
  },
  {
    "path": "include/helper_system_remote_scan",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n######################################################################\n#\n# Helper program to perform a remote scan\n#\n######################################################################\n#\n# Options:\n# ---------\n# 1) lynis update info     - Show version information (external)\n# 2) lynis update release  - Check and install new release (internal)\n#\n# How to use:\n# ------------\n# Run option 1 to know about current and latest release information.\n# Run option 2 to query internal server for possible upgrade of Lynis.\n#\n# Steps for updating to new release:\n# 1) Run Lynis with: lynis update release\n# 2) Lynis will use this helper and check the profile\n# 3) The configured web server will be queried (lynis-latest-version)\n# 4) The contents of this file will be compared with a local file\n# 5) If there is a difference, download package\n# 6) Check paths and extract files\n# 7) Quit program\n#\n# Suggested documentation if you want to use this functionality:\n# https://cisofy.com/documentation/lynis/upgrading/\n#\n######################################################################\n\n    # Enable screen output again\n    QUIET=0\n\n    SCP_BINARY=$(which scp 2> /dev/null | grep -v \"no [^ ]* in \")\n    SSH_BINARY=$(which ssh 2> /dev/null | grep -v \"no [^ ]* in \")\n    if [ \"${SCP_BINARY}\" = \"\" ]; then echo \"Could not find scp binary\"; ExitFatal; fi\n    if [ \"${SSH_BINARY}\" = \"\" ]; then echo \"Could not find ssh binary\"; ExitFatal; fi\n\n    LYNIS_TARBALL=\"lynis-remote.tar.gz\"\n    echo \"\"\n    echo  \"  ${BLUE}* ${WHITE}Step 1${NORMAL}: ${CYAN}Create tarball${NORMAL}\"\n    printf \"%s\\n\\n\" \"    mkdir -p ./files && cd .. && tar czf ./lynis/files/${LYNIS_TARBALL} --exclude=files/${LYNIS_TARBALL} ./lynis && cd lynis\"\n\n    echo \"  ${BLUE}* ${WHITE}Step 2${NORMAL}: ${CYAN}Copy tarball to target ${REMOTE_TARGET}${NORMAL}\"\n    LYNIS_TARBALL=\"./files/lynis-remote.tar.gz\"\n    printf \"%s\\n\\n\" \"    scp -q ${LYNIS_TARBALL} ${REMOTE_TARGET}:~/tmp-lynis-remote.tgz\"\n    #if [ $? -gt 0 ]; then echo \"Could not copy tarball to target\"; ExitFatal; fi\n\n    echo \"  ${BLUE}* ${WHITE}Step 3${NORMAL}: ${CYAN}Execute audit command${NORMAL}\"\n\n    printf \"%s\\n\\n\" \"    ssh ${REMOTE_TARGET} \\\"mkdir -p ~/tmp-lynis && cd ~/tmp-lynis && tar xzf ../tmp-lynis-remote.tgz && rm ../tmp-lynis-remote.tgz && cd lynis && ${REMOTE_COMMAND}\\\"\"\n    #if [ $? -gt 1 ]; then echo \"Could not perform remote audit\"; ExitFatal; fi\n\n    echo \"  ${BLUE}* ${WHITE}Step 4${NORMAL}: ${CYAN}Clean up directory${NORMAL}\"\n    printf \"%s\\n\\n\" \"    ssh ${REMOTE_TARGET} \\\"rm -rf ~/tmp-lynis\\\"\"\n\n    echo \"  ${BLUE}* ${WHITE}Step 5${NORMAL}: ${CYAN}Retrieve log and report${NORMAL}\"\n    printf \"%s\\n\" \"    scp -q ${REMOTE_TARGET}:/tmp/lynis.log ./files/${REMOTE_TARGET}-lynis.log\"\n    printf \"%s\\n\\n\" \"    scp -q ${REMOTE_TARGET}:/tmp/lynis-report.dat ./files/${REMOTE_TARGET}-lynis-report.dat\"\n\n    echo \"  ${BLUE}* ${WHITE}Step 6${NORMAL}: ${CYAN}Clean up tmp files (when using non-privileged account)${NORMAL}\"\n    printf \"%s\\n\\n\" \"    ssh ${REMOTE_TARGET} \\\"rm /tmp/lynis.log /tmp/lynis-report.dat\\\"\"\n\n    # No more Lynis output\n    QUIET=1\n\n# EOF\n"
  },
  {
    "path": "include/helper_update",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n######################################################################\n#\n# Helper program to support automatic updates of Lynis\n#\n######################################################################\n#\n# Options:\n# ---------\n# 1) lynis update info     - Show version information (external)\n#\n# How to use:\n# ------------\n# Run option 1 to know about current and latest release information.\n#\n######################################################################\n\nLOCAL_VERSION=\"-\"\nRUN_UPDATE_CHECK=1\nSERVER_VERSION=\"\"\nPERFORM_UPGRADE=0\nQUIET=0\n\nWGET_EXISTS=$(which wget 2> /dev/null | grep -v \"no [^ ]* in \")\nCURL_EXISTS=$(which curl 2> /dev/null | grep -v \"no [^ ]* in \")\nFETCH_EXISTS=$(which fetch 2> /dev/null | grep -v \"no [^ ]* in \")\n\n# Update version\nif [ \"$1\" = \"release\" ]; then\n\n    ${ECHOCMD} \"Deprecated: this function is no longer available. Use a package (https://packages.cisofy.com), or deploy via a custom package or script.\"\n\n# Update check\nelif [ \"$1\" = \"info\" ]; then\n\n        # CV - Current Version\n        PROGRAM_AC=$(echo ${PROGRAM_VERSION} | awk '{ print $1 }' | sed 's/[.]//g')\n        PROGRAM_LV=0\n\n        CheckUpdates\n\n        # Reset everything if we can't determine our current version or the latest\n        # available version (due lack of internet connectivity for example)\n        if [ \"${PROGRAM_AC}\" = \"\" -o \"${PROGRAM_LV}\" = \"\" ]; then\n            # Set both to safe values\n            PROGRAM_AC=0; PROGRAM_LV=0\n        fi\n\n        echo \"\"; echo \" == ${WHITE}${PROGRAM_NAME}${NORMAL} ==\"\n        echo \"\"\n        echo \"  Version            : ${PROGRAM_VERSION}\"\n        echo -n \"  Status             : \"\n        if [ ${PROGRAM_LV} -eq 0 ]; then\n            echo \"${RED}Unknown${NORMAL}\";\n        elif [ ${PROGRAM_LV} -gt ${PROGRAM_AC} ]; then\n            echo \"${YELLOW}Outdated${NORMAL}\";\n            echo \"  Installed version  : ${PROGRAM_AC}\"\n            echo \"  Latest version     : ${PROGRAM_LV}\"\n        else\n            echo \"${GREEN}Up-to-date${NORMAL}\"\n        fi\n        echo \"  Release date       : ${PROGRAM_RELEASE_DATE}\"\n        echo \"  Project page       : ${PROGRAM_WEBSITE}\"\n        echo \"  Source code        : ${PROGRAM_SOURCE}\"\n        echo \"  Latest package     : ${PROGRAM_PACKAGE}\"\n        echo \"\"; echo \"\"\n        echo \"${PROGRAM_COPYRIGHT}\"\n        echo \"\"\n\n# Check if there is an update, display status on screen and use exit code to tell status as well\nelif [ \"$1\" = \"check\" ]; then\n        # CV - Current Version, LV - Latest Version\n        PROGRAM_CV=$(echo ${PROGRAM_VERSION} | awk '{ print $1 }' | sed 's/[.]//g')\n        PROGRAM_LV=0\n        CheckUpdates\n        if [ \"${PROGRAM_CV}\" = \"\" -o \"${PROGRAM_LV}\" = \"\" ]; then PROGRAM_AC=0; PROGRAM_LV=0; fi\n        if [ ${PROGRAM_LV} -eq 0 ]; then\n            echo \"status=unknown\";\n            ExitCustom 1\n        elif [ ${PROGRAM_LV} -gt ${PROGRAM_CV} ]; then\n            echo \"status=outdated\";\n            ExitCustom 1\n        else\n            echo \"status=up-to-date\"\n            ExitClean\n        fi\n\nelse\n    ${ECHOCMD} \"${RED}Error: ${WHITE}Unknown parameter $1.${NORMAL} Aborting..\"\n    ExitFatal\nfi\n\nExitClean\n\nQUIET=1\n\n# EOF\n"
  },
  {
    "path": "include/osdetection",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Operating System detection\n#\n#################################################################################\n# \n# Variables:\n# OS is primary operating system name (e.g. Linux)\n# OS_NAME is typically the name that people will refer it to (e.g. Debian)\n# OS_VERSION is usually the major version (12) or major and minor version (12.9)\n# OS_FULLNAME is the operating system name and version (often OS_NAME + OS_VERSION)\n#\n#################################################################################\n#\n    # Check operating system\n    case $(uname) in\n\n        # IBM AIX\n        AIX)\n            OS=\"AIX\"\n            OS_NAME=\"AIX\"\n            OS_VERSION=$(oslevel)\n            OS_FULLNAME=\"AIX ${OS_VERSION}\"\n            CPU=$(uname -p)\n            HARDWARE=$(uname -M)\n            FIND_BINARIES=\"whereis -b\"\n            SYSCTL_READKEY=\"\"\n        ;;\n\n        # Mac OS X and macOS\n        Darwin)\n            OS=\"macOS\"\n            if [ -x /usr/bin/sw_vers ]; then\n                OS_NAME=$(/usr/bin/sw_vers -productName)\n                OS_VERSION=$(/usr/bin/sw_vers -productVersion)\n                OS_VERSION_NAME=\"unknown\"\n                OS_FULLNAME=\"macOS (unknown version)\"\n                case ${OS_VERSION} in\n                    10.0 | 10.0.[0-9]*) OS_FULLNAME=\"Mac OS X 10.0 (Cheetah)\" ;;\n                    10.1 | 10.1.[0-9]*) OS_FULLNAME=\"Mac OS X 10.1 (Puma)\" ;;\n                    10.2 | 10.2.[0-9]*) OS_FULLNAME=\"Mac OS X 10.2 (Jaguar)\" ;;\n                    10.3 | 10.3.[0-9]*) OS_FULLNAME=\"Mac OS X 10.3 (Panther)\" ;;\n                    10.4 | 10.4.[0-9]*) OS_FULLNAME=\"Mac OS X 10.4 (Tiger)\" ;;\n                    10.5 | 10.5.[0-9]*) OS_FULLNAME=\"Mac OS X 10.5 (Leopard)\" ;;\n                    10.6 | 10.6.[0-9]*) OS_FULLNAME=\"Mac OS X 10.6 (Snow Leopard)\" ;;\n                    10.7 | 10.7.[0-9]*) OS_FULLNAME=\"Mac OS X 10.7 (Lion)\" ;;\n                    10.8 | 10.8.[0-9]*) OS_FULLNAME=\"Mac OS X 10.8 (Mountain Lion)\" ;;\n                    10.9 | 10.9.[0-9]*) OS_FULLNAME=\"Mac OS X 10.9 (Mavericks)\" ;;\n                    10.10 | 10.10.[0-9]*) OS_FULLNAME=\"Mac OS X 10.10 (Yosemite)\" ;;\n                    10.11 | 10.11.[0-9]*) OS_FULLNAME=\"Mac OS X 10.11 (El Capitan)\" ;;\n                    10.12 | 10.12.[0-9]*) OS_FULLNAME=\"macOS Sierra (${OS_VERSION})\" ;;\n                    10.13 | 10.13.[0-9]*) OS_FULLNAME=\"macOS High Sierra (${OS_VERSION})\" ;;\n                    10.14 | 10.14.[0-9]*) OS_FULLNAME=\"macOS Mojave (${OS_VERSION})\" ;;\n                    10.15 | 10.15.[0-9]*) OS_FULLNAME=\"macOS Catalina (${OS_VERSION})\" ;;\n                    11 | 11.[0-9]*) OS_FULLNAME=\"macOS Big Sur (${OS_VERSION})\" ;;\n                    12 | 12.[0-9]*) OS_FULLNAME=\"macOS Monterey (${OS_VERSION})\" ;;\n                    13 | 13.[0-9]*) OS_FULLNAME=\"macOS Ventura (${OS_VERSION})\" ;;\n                    14 | 14.[0-9]*) OS_FULLNAME=\"macOS Sonoma (${OS_VERSION})\" ;;\n                    15 | 15.[0-9]*) OS_FULLNAME=\"macOS Sequoia (${OS_VERSION})\" ;;\n                    26 | 26.[0-9]*) OS_FULLNAME=\"macOS Tahoe (${OS_VERSION})\" ;;\n                    *) echo \"Unknown macOS version. Do you know what version it is? Create an issue at ${PROGRAM_SOURCE}\" ;;\n                esac\n            else\n                # Fall back to a fairly safe name\n                OS_NAME=\"macOS\"\n                # uname -s -r shows Darwin 16.1.0\n                OS_FULLNAME=$(uname -s -r)\n                # shows 16.1.0 for Darwin's version, not macOS's\n                OS_VERSION=$(uname -r)\n            fi\n            HARDWARE=$(uname -m)\n            HOMEDIRS=\"/Users\"\n            FIND_BINARIES=\"whereis\"\n            OS_KERNELVERSION=$(uname -r)\n            SYSCTL_READKEY=\"\"\n        ;;\n\n        # DragonFly BSD\n        DragonFly)\n            OS=\"DragonFly\"\n            OS_NAME=\"DragonFly BSD\"\n            OS_FULLNAME=$(uname -s -r)\n            OS_VERSION=$(uname -r)\n            HARDWARE=$(uname -m)\n            HOMEDIRS=\"/home /root\"\n            FIND_BINARIES=\"whereis -q -a -b\"\n            OS_KERNELVERSION=$(uname -i)\n            SYSCTL_READKEY=\"sysctl -n\"\n        ;;\n\n        # FreeBSD\n        FreeBSD)\n            OS=\"FreeBSD\"\n            OS_NAME=\"FreeBSD\"\n            OS_FULLNAME=$(uname -s -r)\n            OS_VERSION=$(uname -r)\n            HARDWARE=$(uname -m)\n            HOMEDIRS=\"/home /root\"\n            FIND_BINARIES=\"whereis -q -a -b\"\n            OS_KERNELVERSION=$(uname -i)\n            SYSCTL_READKEY=\"sysctl -n\"\n\n            # TrueOS\n            if [ -f /etc/defaults/trueos ]; then\n                OS_NAME=\"TrueOS\"\n                LogText \"Result: found TrueOS file, system is completely based on FreeBSD though. Only adjusting OS name.\"\n            fi\n        ;;\n\n        # HP-UX\n        HP-UX)\n            OS=\"HP-UX\"\n            OS_NAME=\"HP-UX\"\n            OS_FULLNAME=$(uname -s -r)\n            OS_VERSION=$(uname -r)\n            HARDWARE=$(uname -m)\n            FIND_BINARIES=\"whereis -b\"\n            SYSCTL_READKEY=\"\"\n            LOGDIR=\"/var/adm/syslog\"\n        ;;\n\n        # Linux\n        Linux)\n            OS=\"Linux\"\n            OS_NAME=\"Linux\"\n            OS_FULLNAME=\"\"\n            OS_VERSION=$(uname -r)\n            LINUX_VERSION=\"\"\n            HARDWARE=$(uname -m)\n            HOMEDIRS=\"/home\"\n            FIND_BINARIES=\"whereis -b\"\n            OS_KERNELVERSION_FULL=$(uname -r)\n            OS_KERNELVERSION=$(echo ${OS_KERNELVERSION_FULL} | sed 's/-.*//')\n            if [ -e /dev/grsec ]; then GRSEC_FOUND=1; fi\n\n            # Generic\n            if [ -e /etc/os-release ]; then\n                OS_FULLNAME=$(awk -F= '/^PRETTY_NAME=/ {print substr($2,2,length($2)-2)}' /etc/os-release)\n                OS_ID=$(grep \"^ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                if [ -n \"${OS_ID}\" ]; then\n                    case ${OS_ID} in\n                        \"almalinux\")\n                            LINUX_VERSION=\"AlmaLinux\"\n                            OS_NAME=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')                           \n                        ;;\n                        \"alpine\")\n                            LINUX_VERSION=\"Alpine Linux\"\n                            OS_NAME=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"altlinux\")\n                            LINUX_VERSION=\"ALT Linux\"\n                            OS_NAME=\"altlinux\"\n                            OS_VERSION=$(grep \"^ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"amzn\")\n                            LINUX_VERSION=\"Amazon Linux\"\n                            OS_NAME=\"Amazon Linux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"arch\")\n                            LINUX_VERSION=\"Arch Linux\"\n                            OS_FULLNAME=\"Arch Linux\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"archarm\")\n                            LINUX_VERSION=\"Arch Linux ARM\"\n                            OS_FULLNAME=\"Arch Linux ARM\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"arch32\")\n                            LINUX_VERSION=\"Arch Linux 32\"\n                            OS_FULLNAME=\"Arch Linux 32\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"arcolinux\")\n                            LINUX_VERSION=\"ArcoLinux\"\n                            OS_FULLNAME=\"ArcoLinux\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"artix\")\n                            LINUX_VERSION=\"Artix Linux\"\n                            OS_FULLNAME=\"Artix Linux\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"athena\")\n                            LINUX_VERSION=\"Athena OS\"\n                            OS_NAME=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"buildroot\")\n                            LINUX_VERSION=\"Buildroot\"\n                            OS_NAME=\"Buildroot\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"bunsenlabs\")\n                            LINUX_VERSION=\"BunsenLabs\"\n                            OS_NAME=\"BunsenLabs\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"cachyos\")\n                            LINUX_VERSION=\"CachyOS\"\n                            OS_FULLNAME=\"CachyOS\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"centos\")\n                            LINUX_VERSION=\"CentOS\"\n                            OS_NAME=\"CentOS Linux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"clear-linux-os\")\n                            LINUX_VERSION=\"Clear Linux OS\"\n                            OS_NAME=\"Clear Linux OS\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"cloudlinux\")\n                            LINUX_VERSION=\"CloudLinux\"\n                            OS_NAME=\"CloudLinux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"coreos\")\n                            LINUX_VERSION=\"CoreOS\"\n                            OS_NAME=\"CoreOS Linux\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"cos\")\n                            LINUX_VERSION=\"Container-Optimized OS\"\n                            OS_NAME=\"Container-Optimized OS from Google\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"debian\")\n                            LINUX_VERSION=\"Debian\"\n                            OS_NAME=\"Debian\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_FULLNAME=\"${OS_NAME} ${OS_VERSION}\"\n                        ;;                     \n                        \"devuan\")\n                            LINUX_VERSION=\"Devuan\"\n                            OS_NAME=\"Devuan\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"elementary\")\n                            LINUX_VERSION=\"elementary OS\"\n                            OS_NAME=\"elementary OS\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"endeavouros\")\n                            LINUX_VERSION=\"EndeavourOS\"\n                            OS_NAME=\"EndeavourOS\"\n                            OS_VERSION=\"Rolling release\"\n                            OS_VERSION_FULL=\"Rolling release\"\n                        ;;\n                        \"fedora\")\n                            LINUX_VERSION=\"Fedora\"\n                            OS_NAME=\"Fedora Linux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"fedora-asahi-remix\")\n                            LINUX_VERSION=\"Fedora\"\n                            OS_NAME=\"Fedora Linux Asahi Remix\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"flatcar\")\n                            LINUX_VERSION=\"Flatcar\"\n                            LINUX_VERSION_LIKE=\"CoreOS\"\n                            OS_NAME=\"Flatcar Linux\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"funtoo\")\n                            LINUX_VERSION=\"Funtoo\"\n                            OS_FULLNAME=\"Funtoo Linux\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"gardenlinux\")\n                            LINUX_VERSION=\"Garden Linux\"\n                            LINUX_VERSION_LIKE=\"Debian\"\n                            OS_NAME=$(grep \"^NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION=$(grep \"^GARDENLINUX_VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^GARDENLINUX_VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"garuda\")\n                            LINUX_VERSION=\"Garuda\"\n                            OS_FULLNAME=\"Garuda Linux\"\n                            OS_NAME=\"Garuda\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"gentoo\")\n                            LINUX_VERSION=\"Gentoo\"\n                            OS_NAME=\"Gentoo Linux\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"guix\")\n                            LINUX_VERSION=\"Guix\"\n                            OS_FULLNAME=\"Guix System\"\n                            OS_NAME=\"Guix\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"ipfire\")\n                            LINUX_VERSION=\"IPFire\"\n                            OS_NAME=\"IPFire\"\n                            OS_VERSION=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"kali\")\n                            LINUX_VERSION=\"Kali\"\n                            LINUX_VERSION_LIKE=\"Debian\"\n                            OS_NAME=\"Kali Linux\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"koozali\")\n                            LINUX_VERSION=\"Koozali\"\n                            OS_NAME=\"Koozali SME Server\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"linuxmint\")\n                            LINUX_VERSION=\"Linux Mint\"\n                            LINUX_VERSION_LIKE=\"Ubuntu\"\n                            OS_NAME=\"Linux Mint\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"lsdk\")\n                            LINUX_VERSION=\"NXP LSDK\"\n                            OS_NAME=\"NXP LSDK\"\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"mageia\")\n                            LINUX_VERSION=\"Mageia\"\n                            OS_NAME=\"Mageia\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"manjaro\" | \"manjaro-arm\")\n                            LINUX_VERSION=\"Manjaro\"\n                            OS_FULLNAME=\"Manjaro Linux\"\n                            OS_NAME=\"Manjaro\"\n                            OS_VERSION=\"Rolling release\"\n                        ;;\n                        \"neon\")\n                            LINUX_VERSION=\"KDE Neon\"\n                            LINUX_VERSION_LIKE=\"Ubuntu\"\n                            OS_NAME=\"KDE Neon\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"nethserver\")\n                            LINUX_VERSION=\"NethServer\"\n                            OS_NAME=\"NethServer\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"nixos\")\n                            LINUX_VERSION=\"NixOS\"\n                            OS_NAME=\"NixOS\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"ol\")\n                            LINUX_VERSION=\"Oracle Linux\"\n                            OS_NAME=\"Oracle Linux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"nobara\")\n                            LINUX_VERSION=\"Nobara\"\n                            OS_NAME=\"Nobara Linux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"nodistro\")\n                            LINUX_VERSION=\"openembedded\"\n                            OS_NAME=\"OpenEmbedded\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"openmandriva\")\n                            LINUX_VERSION=\"OpenMandriva Lx\"\n                            OS_NAME=\"OpenMandriva Lx\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"opensuse-tumbleweed\")\n                            LINUX_VERSION=\"openSUSE Tumbleweed\"\n                            # It's rolling release but has a snapshot version (the date of the snapshot)\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"openSUSE\"\n                        ;;\n                        \"opensuse-slowroll\")\n                            LINUX_VERSION=\"openSUSE Tumbleweed-Slowroll\"\n                            # It's rolling release but has a snapshot version (the date of the snapshot)\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"openSUSE\"\n                        ;;\n                        \"opensuse-leap\")\n                            LINUX_VERSION=\"openSUSE Leap\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"openSUSE\"\n                        ;;\n                        \"opensuse-microos\")\n                            LINUX_VERSION=\"openSUSE MicroOS\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"openSUSE\"\n                        ;;\n                        \"osmc\")\n                            LINUX_VERSION=\"OSMC\"\n                            LINUX_VERSION_LIKE=\"Debian\"\n                            OS_NAME=\"Open Source Media Center\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"parrot\")\n                            LINUX_VERSION=\"Parrot\"\n                            OS_NAME=\"Parrot GNU/Linux\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"peppermint\")\n                            LINUX_VERSION=\"Peppermint OS\"\n                            LINUX_VERSION_LIKE=\"Debian\"\n                            OS_NAME=\"Peppermint OS\"\n                            OS_VERSION=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION_CODENAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"poky\")\n                            LINUX_VERSION=\"Poky\"\n                            OS_NAME=\"openembedded\"\n                            LINUX_VERSION_LIKE=\"openembedded\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n\n                        ;;\n                        \"pop\")\n                            LINUX_VERSION=\"Pop!_OS\"\n                            LINUX_VERSION_LIKE=\"Ubuntu\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"Pop!_OS\"\n                        ;;\n                        \"postmarketos\")\n                            LINUX_VERSION=\"PostmarketOS\"\n                            LINUX_VERSION_LIKE=\"Alpine\"\n                            OS_NAME=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"pureos\")\n                            LINUX_VERSION=\"PureOS\"\n                            LINUX_VERSION_LIKE=\"Debian\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"PureOS\"\n                        ;;\n                        \"raspbian\")\n                            LINUX_VERSION=\"Raspbian\"\n                            LINUX_VERSION_LIKE=\"Debian\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"Raspbian\"\n                        ;;\n                        \"redhat\" | \"rhel\")\n                            LINUX_VERSION=\"RHEL\"\n                            OS_NAME=\"RHEL\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_FULLNAME=\"${OS_NAME} ${OS_VERSION_FULL}\"\n                            OS_REDHAT_OR_CLONE=1\n                        ;;\n                         \"rocky\")\n                            LINUX_VERSION=\"Rocky Linux\"\n                            OS_NAME=\"Rocky Linux\"\n                            OS_REDHAT_OR_CLONE=1\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"rosa\")\n                            LINUX_VERSION=\"ROSA Linux\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"ROSA Linux\"\n                        ;;\n                        \"slackware\")\n                            LINUX_VERSION=\"Slackware\"\n                            OS_NAME=\"Slackware Linux\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"sles\")\n                            LINUX_VERSION=\"SLES\"\n                            OS_NAME=\"openSUSE\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^PRETTY_NAME=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        \"ubuntu\")\n                            LINUX_VERSION=\"Ubuntu\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_NAME=\"Ubuntu\"\n                        ;;\n                        \"void\")\n                            LINUX_VERSION=\"Void Linux\"\n                            OS_VERSION=\"Rolling release\"\n                            OS_NAME=\"Void Linux\"\n                        ;;\n                        \"zorin\")\n                            LINUX_VERSION=\"Zorin OS\"\n                            OS_NAME=\"Zorin OS\"\n                            OS_VERSION=$(grep \"^VERSION_ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                            OS_VERSION_FULL=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                        ;;\n                        *)\n                            ReportException \"OS Detection\" \"Unknown OS found in /etc/os-release - Please create an issue on GitHub and share the contents (cat /etc/os-release): ${PROGRAM_SOURCE}\"\n                        ;;\n                    esac\n                fi\n            fi\n\n            # Alpine\n            if [ -e \"/etc/alpine-release\" ]; then LINUX_VERSION=\"Alpine Linux\"; OS_VERSION=$(cat /etc/alpine-release); fi\n\n            # Amazon\n            if [ -z \"${LINUX_VERSION}\" -a -e \"/etc/system-release\" ]; then\n                FIND=$(grep \"^Amazon\" /etc/system-release)\n                if [ -n \"${FIND}\" ]; then\n                    OS_REDHAT_OR_CLONE=1\n                    OS_FULLNAME=$(grep \"^Amazon\" /etc/system-release)\n                    OS_VERSION=$(grep \"^Amazon\" /etc/system-release | awk '{ if ($4==\"release\") { print $5 } }')\n                    LINUX_VERSION=\"Amazon\"\n                fi\n            fi\n\n            # Arch Linux\n            if [ -z \"${OS_FULLNAME}\" -a -e \"/etc/arch-release\" ]; then\n                OS_FULLNAME=\"Arch Linux\"\n                OS_VERSION=\"Unknown\"\n                LINUX_VERSION=\"Arch Linux\"\n            fi\n\n            # Chakra Linux\n            if [ -e \"/etc/chakra-release\" ]; then\n                OS_FULLNAME=$(grep \"^Chakra\" /etc/chakra-release)\n                OS_VERSION=$(awk '/^Chakra/ { if ($3==\"release\") { print $4 }}' /etc/chakra-release)\n                LINUX_VERSION=\"Chakra Linux\"\n            fi\n\n            # Cobalt\n            if [ -e \"/etc/cobalt-release\" ]; then OS_FULLNAME=$(cat /etc/cobalt-release); fi\n\n            # CPUBuilders Linux\n            if [ -e \"/etc/cpub-release\" ]; then OS_FULLNAME=$(cat /etc/cpub-release); fi\n\n            if [ -z \"${LINUX_VERSION}\" ] && [ -e \"/etc/debian_version\" ]; then\n                # Debian/Ubuntu (***) - Set first to Debian\n                OS_VERSION=$(cat /etc/debian_version)\n                OS_FULLNAME=\"Debian ${OS_VERSION}\"\n                LINUX_VERSION=\"Debian\"\n\n                # /etc/lsb-release does not exist on Debian\n                if [ -e /etc/lsb-release ]; then\n                    OS_VERSION=$(cat /etc/debian_version)\n                    FIND=$(grep \"^DISTRIB_ID=\" /etc/lsb-release | cut -d '=' -f2 | sed 's/\"//g')\n                    if [ \"${FIND}\" = \"Ubuntu\" ]; then\n                        OS_VERSION=$(grep \"^DISTRIB_RELEASE=\" /etc/lsb-release | cut -d '=' -f2)\n                        OS_FULLNAME=\"Ubuntu ${OS_VERSION}\"\n                        LINUX_VERSION=\"Ubuntu\"\n                    elif [ \"${FIND}\" = \"elementary OS\" ]; then\n                        LINUX_VERSION=\"elementary OS\"\n                        LINUX_VERSION_LIKE=\"Ubuntu\"\n                        OS_VERSION=$(grep \"^DISTRIB_RELEASE=\" /etc/lsb-release | cut -d '=' -f2)\n                        OS_FULLNAME=$(grep \"^DISTRIB_DESCRIPTION=\" /etc/lsb-release | cut -d '=' -f2 | sed 's/\"//g')\n                    else\n                        # Catch all, in case it's unclear what specific release this is.\n                        OS_FULLNAME=\"Debian ${OS_VERSION}\"\n                        LINUX_VERSION=\"Debian\"\n                    fi\n                    # Ubuntu test (optional) $(grep \"[Uu]buntu\" /proc/version)\n                fi\n            fi\n\n            # Override for Linux Mint, as that is initially detected as Debian or Ubuntu\n            if [ -x /usr/bin/lsb_release ]; then\n                FIND=$(lsb_release --id | awk -F: '{ print $2 }' | awk '{ print $1 }')\n                if [ \"${FIND}\" = \"LinuxMint\" ]; then\n                    LINUX_VERSION=\"Linux Mint\"\n                    # LMDE (Linux Mint Debian Edition) should be detected as Debian\n                    LINUX_VERSION_LIKE=\"Ubuntu\"\n                    OS_VERSION=$(lsb_release --release | awk '{ print $2 }')\n                    OS_FULLNAME=\"Linux Mint ${OS_VERSION}\"\n                fi\n            fi\n\n            # E-smith\n            if [ -e \"/etc/e-smith-release\" ]; then OS_FULLNAME=$(cat /etc/e-smith-release); fi\n\n            # Gentoo\n            if [ -e \"/etc/gentoo-release\" ]; then LINUX_VERSION=\"Gentoo\"; OS_FULLNAME=$(cat /etc/gentoo-release); fi\n\n            # Red Hat and others\n            if [ -z \"${LINUX_VERSION}\" -a -e \"/etc/redhat-release\" ]; then\n                OS_REDHAT_OR_CLONE=1\n\n                # CentOS\n                if grep \"CentOS\" /etc/redhat-release; then\n                    OS_FULLNAME=$(grep \"CentOS\" /etc/redhat-release)\n                    LINUX_VERSION=\"CentOS\"\n                    OS_VERSION=\"${OS_FULLNAME}\"\n                fi\n\n                # ClearOS\n                FIND=$(grep \"ClearOS\" /etc/redhat-release)\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    OS_FULLNAME=$(grep \"ClearOS\" /etc/redhat-release)\n                    LINUX_VERSION=\"ClearOS\"\n                    OS_VERSION=\"${OS_FULLNAME}\"\n                fi\n\n                # Fedora\n                FIND=$(grep \"Fedora\" /etc/redhat-release)\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    OS_FULLNAME=$(grep \"Fedora\" /etc/redhat-release)\n                    OS_VERSION=\"${OS_FULLNAME}\"\n                    LINUX_VERSION=\"Fedora\"\n                fi\n\n\n                # Oracle Enterprise Linux\n                FIND=$(grep \"Enterprise Linux Enterprise Linux Server\" /etc/redhat-release)\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    LINUX_VERSION=\"Oracle Enterprise Linux\"\n                    OS_FULLNAME=$(grep \"Enterprise Linux\" /etc/redhat-release)\n                    OS_VERSION=\"${OS_FULLNAME}\"\n                fi\n\n                # Oracle Enterprise Linux\n                if [ -e /etc/oracle-release ]; then\n                    FIND=$(grep \"Oracle Linux Server\" /etc/oracle-release)\n                    if [ ! \"${FIND}\" = \"\" ]; then\n                        LINUX_VERSION=\"Oracle Enterprise Linux\"\n                        OS_FULLNAME=$(grep \"Oracle Linux\" /etc/oracle-release)\n                        OS_VERSION=\"${OS_FULLNAME}\"\n                    fi\n                fi\n\n                # Oracle VM Server\n                if [ -e /etc/ovs-release ]; then\n                    FIND=$(grep \"Oracle VM\" /etc/ovs-release)\n                    if [ ! \"${FIND}\" = \"\" ]; then\n                        LINUX_VERSION=\"Oracle VM Server\"\n                        OS_FULLNAME=$(grep \"Oracle VM\" /etc/ovs-release)\n                        OS_VERSION=\"${OS_FULLNAME}\"\n                    fi\n                fi\n\n                # Scientific\n                FIND=$(grep \"Scientific\" /etc/redhat-release)\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    OS_FULLNAME=$(grep \"^Scientific\" /etc/redhat-release)\n                    OS_VERSION=$(grep \"^Scientific\" /etc/redhat-release | awk '{ if ($3==\"release\") { print $4 } }')\n                    LINUX_VERSION=\"Scientific\"\n                fi\n\n                if [ -z \"${LINUX_VERSION}\" ]; then\n                    # Red Hat\n                    FIND=$(grep \"Red Hat\" /etc/redhat-release)\n                    if [ ! \"${FIND}\" = \"\" ]; then\n                        OS_FULLNAME=$(grep \"Red Hat\" /etc/redhat-release)\n                        OS_VERSION=\"${OS_FULLNAME}\"\n                        LINUX_VERSION=\"Red Hat\"\n                    fi\n                fi\n\n            fi\n\n            # PCLinuxOS\n            if [ -f /etc/pclinuxos-release ]; then\n                FIND=$(grep \"^PCLinuxOS\" /etc/pclinuxos-release)\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    OS_FULLNAME=\"PCLinuxOS Linux\"\n                    LINUX_VERSION=\"PCLinuxOS\"\n                    OS_VERSION=$(grep \"^PCLinuxOS\" /etc/pclinuxos-release | awk '{ if ($2==\"release\") { print $3 } }')\n                fi\n            fi\n\n            # Sabayon Linux\n            if [ -f /etc/sabayon-edition ]; then\n                FIND=$(grep \"Sabayon Linux\" /etc/sabayon-edition)\n                if [ ! \"${FIND}\" = \"\" ]; then\n                    OS_FULLNAME=\"Sabayon Linux\"\n                    LINUX_VERSION=\"Sabayon\"\n                    OS_VERSION=$(awk '{ print $3 }' /etc/sabayon-edition)\n                fi\n            fi\n\n            if [ -f /etc/SLOX-release ]; then\n                OS_FULLNAME=$(grep \"SuSE Linux\" /etc/SLOX-release)\n                LINUX_VERSION=\"SuSE\"\n            fi\n\n            # Slackware\n            if [ -f /etc/slackware-version ]; then\n                LINUX_VERSION=\"Slackware\"\n                OS_VERSION=$(grep \"^Slackware\" /etc/slackware-version | awk '{ if ($1==\"Slackware\") { print $2 } }')\n                OS_FULLNAME=\"Slackware Linux ${OS_VERSION}\"\n            fi\n\n            # SuSE\n            if [ -e \"/etc/SuSE-release\" ]; then\n                OS_VERSION=$(head -n 1 /etc/SuSE-release)\n                LINUX_VERSION=\"SuSE\"\n            fi\n\n            # Turbo Linux\n            if [ -e \"/etc/turbolinux-release\" ]; then OS_FULLNAME=$(cat /etc/turbolinux-release); fi\n\n            # YellowDog\n            if [ -e \"/etc/yellowdog-release\" ]; then OS_FULLNAME=$(cat /etc/yellowdog-release); fi\n\n            # VMware\n            if [ -e \"/etc/vmware-release\" ]; then\n                OS_FULLNAME=$(cat /etc/vmware-release)\n                OS_VERSION=$(uname -r)\n                IS_VMWARE_ESXI=$(vmware -vl | grep VMware ESXi)\n                if [ ! \"${IS_VMWARE_ESXI}\" = \"\" ]; then\n                    OS_FULLNAME=\"VMware ESXi ${OS_VERSION}\"\n                fi\n            fi\n\n            # ===================================================================\n            # Set OS name to the discovered Linux version\n            if [ ! \"${LINUX_VERSION}\" = \"\" -a \"${OS_NAME}\" = \"Linux\" ]; then\n                OS_NAME=\"${LINUX_VERSION}\"\n            fi\n            # If Linux version (full name) is unknown, use uname value\n            if [ \"${OS_FULLNAME}\" = \"\" ]; then OS_FULLNAME=$(uname -s -r); fi\n            SYSCTL_READKEY=\"sysctl -n\"\n        ;;\n\n        # NetBSD\n        NetBSD)\n            OS=\"NetBSD\"\n            OS_NAME=\"NetBSD\"\n            OS_FULLNAME=$(uname -s -r)\n            OS_KERNELVERSION=$(uname -v)\n            OS_VERSION=$(uname -r)\n            HARDWARE=$(uname -m)\n            FIND_BINARIES=\"whereis\"\n            SYSCTL_READKEY=\"\"\n        ;;\n\n        # OpenBSD\n        OpenBSD)\n            OS=\"OpenBSD\"\n            OS_NAME=\"OpenBSD\"\n            OS_FULLNAME=$(uname -s -r)\n            OS_KERNELVERSION=$(uname -v)\n            OS_VERSION=$(uname -r)\n            HARDWARE=$(uname -m)\n            FIND_BINARIES=\"whereis\"\n            SYSCTL_READKEY=\"\"\n        ;;\n\n        # Solaris / OpenSolaris / Ilumos ...\n        SunOS)\n            OS=\"Solaris\"\n            OS_KERNELVERSION=$(uname -v)\n            OPENSOLARIS=0\n\n            if [ -f /etc/os-release ]; then\n                OS_ID=$(grep \"^ID=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                OS_VERSION=$(grep \"^VERSION=\" /etc/os-release | awk -F= '{print $2}' | tr -d '\"')\n                OS_FULLNAME=$(awk -F= '/^PRETTY_NAME=/ {print substr($2,2,length($2)-2)}' /etc/os-release)\n                case \"${OS_ID}\" in\n                    \"solaris\")\n                        OS_NAME=\"Oracle Solaris\"\n                        ;;\n                    \"omnios\")\n                        OS_NAME=\"OmniOS\"\n                        OPENSOLARIS=1\n                        ;;\n                    \"tribblix\")\n                        OS_NAME=\"Tribblix\"\n                        OS_FULLNAME=\"Tribblix ${OS_VERSION}\"\n                        OPENSOLARIS=1 \n                        ;;\n                    \"*\")\n                        ReportException \"OS Detection\" \"Unknown OS found in /etc/os-release - Please create issue on GitHub project page: ${PROGRAM_SOURCE}\"\n                        ;;\n                esac\n            elif [ \"$(uname -o 2> /dev/null)\" = \"illumos\" ]; then\n                OPENSOLARIS=1\n        \n                # Solaris has a free form text file with release information\n                if grep \"OpenIndiana\" /etc/release > /dev/null; then\n                    OS_NAME=\"OpenIndiana\"\n                    if grep \"Hipster\" /etc/release > /dev/null; then\n                        OS_VERSION=\"$(tr ' ' '\\n' < /etc/release  | grep '[[:digit:]]\\.[[:digit:]]')\"\n                        OS_FULLNAME=\"OpenIndiana Hipster $OS_VERSION\"\n                    else\n                        OS_VERSION=\"Unknown\"\n                        OS_FULLNAME=\"OpenIndiana (unknown edition)\"\n                    fi\n                elif grep \"OmniOS\" /etc/release > /dev/null; then\n                    OS_NAME=\"OmniOS\"\n                    OS_VERSION=\"$(tr ' ' '\\n' < /etc/release  | grep 'r[[:digit:]]')\"\n                    if grep \"Community Edition\" /etc/release > /dev/null; then\n                        OS_FULLNAME=\"OmniOS Community Edition v11 $OS_VERSION\"\n                    fi\n                elif grep \"SmartOS\" /etc/release > /dev/null; then\n                    OS_NAME=\"SmartOS\"\n                    OS_VERSION=\"-\"\n                    OS_FULLNAME=\"SmartOS\"\n                else\n                    OS_NAME=\"Unknown Illumos\"\n                fi\n            elif grep \"SchilliX\" /etc/release > /dev/null; then\n                OS_NAME=\"SchilliX\"\n                OS_FULLNAME=\"$(head -n 1 /etc/release | xargs)\"\n                OS_VERSION=\"$(echo \"$OS_FULLNAME\" | cut -d '-' -f 2)\"\n\n                OPENSOLARIS=1\n            elif head -n 1 < /etc/release | grep \"Oracle Solaris\" > /dev/null; then\n                OS_NAME=\"Oracle Solaris\"\n                OS_FULLNAME=\"$(head -n 1 /etc/release | xargs)\"\n                OS_VERSION=\"$(head -n 1 < /etc/release | xargs | cut -d ' ' -f 3)\"\n            elif head -n 1 < /etc/release | xargs | grep \"^Solaris \" > /dev/null; then\n                OS_NAME=\"Sun Solaris\"\n                # Example of /etc/release:\n                #   Solaris 10 5/08\n                #   ...\n                #   Solaris 10 10/09 (Update 8)\n                # The first line does not contain the \"Update\" number,\n                # only if present.\n                if tail -1 < /etc/release | xargs | grep \"^Solaris \" > /dev/null; then\n                    OS_FULLNAME=$(tail -1 < /etc/release | xargs)\n                else\n                    OS_FULLNAME=$(head -n 1 < /etc/release | xargs)\n                fi\n                OS_VERSION=$(echo \"$OS_FULLNAME\" | cut -d ' ' -f 2,3)\n            else  # Old behaviour\n                OS_NAME=\"Sun Solaris\"\n                OS_FULLNAME=$(uname -s -r)\n                OS_VERSION=$(uname -r)\n            fi\n\n            HARDWARE=$(uname -m)\n            if [ -x /usr/bin/isainfo ]; then\n                # Returns 32, 64\n                OS_MODE=$(/usr/bin/isainfo -b)\n            fi\n            SYSCTL_READKEY=\"\"\n        ;;\n\n        # VMware products\n        VMkernel)\n            OS=\"VMware\"\n            OS_FULLNAME=\"\"\n            OS_VERSION=\"\"\n            HARDWARE=$(uname -m)\n            if [ -e \"/etc/vmware-release\" ]; then\n                OS_FULLNAME=$(cat /etc/vmware-release)\n                OS_VERSION=$(uname -r)\n            fi\n            HAS_VMWARE_UTIL=$(which vmware 2> /dev/null | grep -v \"no [^ ]* in \")\n            if [ ! \"${HAS_VMWARE_UTIL}\" = \"\" ]; then\n                IS_VMWARE_ESXI=$(vmware -vl | grep VMware ESXi)\n                if [ ! \"${IS_VMWARE_ESXI}\" = \"\" ]; then\n                    OS_NAME=\"VMware ESXi\"\n                    OS_FULLNAME=\"VMware ESXi ${OS_VERSION}\"\n                fi\n            fi\n        ;;\n\n\n        # Unknown or unsupported systems\n        *)\n            echo \"[ ${WARNING}WARNING${NORMAL} ]\"\n            echo \"${WARNING}Error${NORMAL}: ${WHITE}Unknown OS found. No support available yet for this OS or platform...${NORMAL}\"\n            echo \"Please consult the README/documentation for more information.\"\n            exit 1\n        ;;\n\n    esac\n\n    # Set correct echo binary and parameters after detecting operating system\n    ECHONB=\"\"\n\n    case ${OS} in\n        \"AIX\")\n            ECHOCMD=\"echo\";\n            ECHONB=\"printf\"\n        ;;\n        \"DragonFly\"|\"FreeBSD\"|\"NetBSD\")\n            ECHOCMD=\"echo -e\"\n            ECHONB=\"echo -n\"\n            NOW=$(date \"+%s\")\n        ;;\n        \"macOS\" | \"Mac OS X\")\n            ECHOCMD=\"echo\"\n            ECHONB=\"/bin/echo -n\"\n            NOW=$(date \"+%s\")\n        ;;\n\n        \"Solaris\")         \n            ECHOCMD=\"echo\"\n            test -f /usr/ucb/echo && ECHONB=\"/usr/ucb/echo -n\"\n            NOW=$(nawk 'BEGIN{print srand()}')\n        ;;\n        \"Linux\")\n            # Check if dash is used (Debian/Ubuntu)\n            DEFAULT_SHELL=$(ls -l /bin/sh | awk -F'>' '{print $2}')\n            case ${DEFAULT_SHELL} in\n                \" dash\")                 ECHOCMD=\"/bin/echo -e\" ;;\n                *)                       ECHOCMD=\"echo -e\" ;;\n            esac\n            NOW=$(date \"+%s\")\n        ;;\n        *)\n            ECHOCMD=\"echo -e\"\n            NOW=$(date \"+%s\")\n        ;;\n    esac\n    \n    # Check if we have full featured commands, or are using BusyBox as a shell\n    if [ -x /bin/busybox ]; then\n        if [ -L /bin/ps ]; then\n            ShowSymlinkPath /bin/ps\n            if [ \"${SYMLINK}\" = \"/bin/busybox\" ]; then\n                SHELL_IS_BUSYBOX=1\n                LogText \"Result: The device is using Busybox.\"\n            else\n                LogText \"Result: The device is NOT using Busybox.\"\n            fi\n        fi\n    fi\n\n    # Specific checks for hardware\n\n    # Detect if we are using a QNAP NAS\n    if [ -d /share/CACHEDEV1_DATA/.qpkg ]; then\n        QNAP_DEVICE=1\n    fi\n\n    # Check if this OS is end-of-life\n    EOL=255\n    EOL_DATE=\"\"\n    EOL_OS_MATCH=\"\"\n    EOL_STATE=\"\"\n    EOL_TIMESTAMP=0\n    Debug \"Info: determining if we can find end-of-life of this operating system\"\n    if [ -n \"${OS_VERSION}\" ]; then\n        if [ -f \"${DBDIR}/software-eol.db\" ]; then\n            FIND=\"${OS_FULLNAME}\"\n            Debug \"Info: using '${OS_FULLNAME}' to search for end-of-life (partial) match\"\n            EOL_TIMESTAMP=$(awk -v value=\"${FIND}\" -F: '{if ($1==\"os\" && value ~ $2){print $4}}' ${DBDIR}/software-eol.db | head -n 1)\n            if [ -n \"${EOL_TIMESTAMP}\" ]; then\n                EOL_DATE=$(awk -v value=\"${FIND}\" -F: '{if ($1==\"os\" && value ~ $2){print $3}}' ${DBDIR}/software-eol.db | head -n 1)\n                if [ -n \"${EOL_DATE}\" ]; then\n                    EOL_OS_MATCH=$(awk -v value=\"${FIND}\" -F: '{if ($1==\"os\" && value ~ $2){print $2}}' ${DBDIR}/software-eol.db | head -n 1)\n                    Debug \"Found a matching line: ${EOL_OS_MATCH} (timestamp=${EOL_TIMESTAMP}, date=${EOL_DATE})\"\n                    if [ ${NOW} -gt ${EOL_TIMESTAMP} ]; then\n                        EOL=1\n                        EOL_STATE=\"This operating system seems be end-of-life and may no longer receive updates or support!\"\n                        Debug \"Outcome: OS is end-of-life!\"\n                    else\n                        EOL=0\n                        EOL_STATE=\"This operating system seems not to be end-of-life yet\"\n                        Debug \"Outcome: OS is not end-of-life yet\"\n                    fi\n                else\n                    EOL=0\n                fi\n            else\n                Debug \"Could not find a related OS entry. Maybe it needs to be added to the database (${DBDIR}/software-eol.db)?\" \n            fi\n        else\n            Debug \"No end-of-life database found (${DBDIR}/software-eol.db)\"\n        fi\n    else\n        Debug \"No OS version known, so skipped end-of-life check\"\n    fi\n\n\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/parameters",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Parameter checks\n#\n#################################################################################\n#\n    PARAMCOUNT=$#\n\n\n    # Input validation on provided parameters and their arguments\n    COUNT=0\n    for I in \"$@\"; do\n        COUNT=$((COUNT + 1))\n        if ! SafeInput \"${I}\"; then\n            echo \"Execution of ${PROGRAM_NAME} stopped as we found unexpected input or invalid characters in argument ${COUNT}\"\n            echo \"Do you believe this is in error? Let us know: ${PROGRAM_AUTHOR_CONTACT}\"\n            ExitFatal \"Program execution stopped due to security measure\"\n        fi\n    done\n\n    # Parse arguments\n    while [ $# -ge 1 ]; do\n        case $1 in\n            # Helpers first\n            audit)\n                CHECK_BINARIES=0\n                RUN_HELPERS=1\n                HELPER=\"audit\"\n                SKIP_PLUGINS=1\n                RUN_TESTS=0\n                if [ $# -gt 1 ]; then\n                    case $2 in\n                        \"dockerfile\")\n                            if [ $# = 2 ]; then\n                                echo \"${RED}Error: ${WHITE}Missing file name or URL${NORMAL}\"\n                                echo \"Example: $0 audit dockerfile /path/to/Dockerfile\"\n                                ExitFatal\n                            else\n                                shift; shift\n                                CHECK_BINARIES=1\n                                HELPER_PARAMS=\"$1\"\n                                HELPER=\"audit_dockerfile\"\n                                break\n                            fi\n                        ;;\n                        \"system\")\n                            if [ $# -gt 2 ]; then\n                                if [ \"$3\" = \"remote\" ]; then\n                                    #shift\n                                    if [ $# -eq 3 ]; then\n                                        echo \"${RED}Error: ${WHITE}Missing remote location${NORMAL}\"\n                                        echo \"Example: $0 audit system remote 192.168.1.100\"\n                                        ExitFatal\n                                    else\n                                        REMOTE_TARGET=\"$4\"\n                                        shift; shift; shift  # shift out first three arguments\n                                        EXTRA_PARAMS=\"\"\n                                        if [ ! \"$1\" = \"\" ]; then EXTRA_PARAMS=\" $@\"; fi\n                                        REMOTE_COMMAND=\"./lynis audit system\"\n                                        echo \"\"\n                                        echo \"  How to perform a remote scan:\"\n                                        echo \"  =============================\"\n                                        echo \"  Target  : ${REMOTE_TARGET}\"\n                                        echo \"  Command : ${REMOTE_COMMAND}\"\n                                        HELPER=\"system_remote_scan\"\n                                        HELPER_PARAMS=\"$@\"\n                                        CHECK_BINARIES=0\n                                        QUIET=1\n                                        RUN_HELPERS=1\n                                        SKIP_PLUGINS=1\n                                        RUN_TESTS=0\n                                        SHOW_PROGRAM_DETAILS=0\n                                        break\n                                    fi\n                                fi\n                            fi\n                            CHECK=1\n                            CHECK_BINARIES=1\n                            HELPER=\"\"\n                            SKIP_PLUGINS=0\n                            RUN_TESTS=1\n                            shift\n                        ;;\n                        *)\n                            echo \"${RED}Error: ${WHITE}Need a target to audit${NORMAL}\"\n                            echo \" \"\n                            echo \"Examples:\"\n                            echo \"lynis audit dockerfile\"\n                            echo \"lynis audit system\"\n                            ExitFatal\n                        ;;\n                    esac\n                else\n                    echo \"${RED}Error: ${WHITE}Need a target to audit${NORMAL}\"\n                    echo \" \"\n                    echo \"Examples:\"\n                    echo \"lynis audit dockerfile\"\n                    echo \"lynis audit system\"\n                    ExitFatal\n                fi\n            ;;\n\n            # Configure Lynis\n            configure)\n                CHECK_BINARIES=0\n                RUN_HELPERS=1\n                QUIET=1\n                SKIP_PLUGINS=1\n                RUN_TESTS=0\n                SHOW_PROGRAM_DETAILS=0\n                if [ $# -gt 0 ]; then shift; fi\n                HELPER=\"configure\"\n                HELPER_PARAMS=\"$@\"\n                break\n            ;;\n\n            # Generate data\n            generate)\n                CHECK_BINARIES=0\n                HELPER=\"generate\"\n                LOGTEXT=0\n                QUIET=1\n                RUN_HELPERS=1\n                RUN_TESTS=0\n                RUN_UPDATE_CHECK=0\n                SKIP_GETHOSTID=1\n                SKIP_PLUGINS=1\n                SKIP_VM_DETECTION=1\n                SHOW_PROGRAM_DETAILS=0\n                SHOW_TOOL_TIPS=0\n                shift; HELPER_PARAMS=\"$@\"\n                break\n            ;;\n\n            # Show Lynis details\n            show)\n                CHECK_BINARIES=0\n                HELPER=\"show\"\n                LOGTEXT=0\n                QUIET=1\n                RUN_HELPERS=1\n                RUN_TESTS=0\n                RUN_UPDATE_CHECK=0\n                SKIP_PLUGINS=1\n                SHOW_PROGRAM_DETAILS=0\n                SHOW_TOOL_TIPS=0\n                shift; HELPER_PARAMS=\"$@\"\n                break\n            ;;\n\n            update)\n                CHECK_BINARIES=0\n                RUN_HELPERS=1\n                HELPER=\"update\"\n                QUIET=1\n                SKIP_PLUGINS=1\n                RUN_TESTS=0\n                RUN_UPDATE_CHECK=0\n                SHOW_PROGRAM_DETAILS=0\n                SHOW_TOOL_TIPS=0\n                if [ $# -gt 1 ]; then\n                    shift\n                    HELPER_PARAMS=\"$1\"\n                    break\n                else\n                    echo \"${RED}Error: ${WHITE}Need a target for update${NORMAL}\"\n                    echo \" \"\n                    echo \"Examples:\"\n                    echo \"lynis update check\"\n                    echo \"lynis update info\"\n                    ExitFatal\n                fi\n            ;;\n\n            # Perform just the upload\n            \"upload-only\" | \"only-upload\")\n                CHECK_BINARIES=1\n                CREATE_REPORT_FILE=0\n                #QUIET=1\n                LOGTEXT=0\n                RUN_HELPERS=0\n                RUN_TESTS=0\n                RUN_UPDATE_CHECK=0\n                SKIP_PLUGINS=1\n                SHOW_REPORT=0\n                SHOW_TOOL_TIPS=0\n                SHOW_PROGRAM_DETAILS=0\n                UPLOAD_DATA=1\n                if [ $# -gt 1 ]; then echo \"No other parameters or options are allowed when using 'upload-only' command\"; ExitFatal; fi\n            ;;\n\n            # Assign auditor to report\n            --auditor)\n                shift\n                AUDITORNAME=$1\n            ;;\n\n            # Binary directories (useful for incident response)\n            --bindirs | --bin-dirs)\n                if [ $# -gt 1 ]; then\n                    shift\n                    DIRS=\"$1\"\n                    for DIR in $1; do\n                        if [ ! -d ${DIR} ]; then\n                            echo \"Invalid bindir '${DIR}' provided (does not exist)\"\n                            exit 1\n                        fi\n                    done\n                    BIN_PATHS=\"${DIRS}\"\n                else\n                    echo \"Need one or more directories (e.g. \\\"/mnt/cert/bin /mnt/cert/sbin\\\")\"\n                    exit 1\n                fi\n            ;;\n\n            # Cronjob support\n            --cron-job | --cronjob | --cron)\n                CRONJOB=1\n                CHECK=1; COLORS=0; NEVERBREAK=1 # Use some defaults ('audit system', -Q, no colors)\n                RemoveColors\n            ;;\n\n            # Perform tests with additional debugging information on screen\n            --debug)\n                DEBUG=1\n            ;;\n\n            # Developer mode (more details when creating tests)\n            --developer)\n                DEVELOPER_MODE=1\n            ;;\n\n            # DevOps mode (continuous integration)\n            --devops)\n                DEVOPS_MODE=1\n            ;;\n\n            # Enable forensics mode (gather information from a mounted directory)\n            --forensics)\n                FORENSICS=1\n            ;;\n\n            # View help\n            --help | -h | \"-?\")\n                VIEWHELP=1\n            ;;\n\n            # Adjust default logfile location\n            --logfile | --log-file)\n                shift\n                LOGFILE=$1\n            ;;\n\n            # Don't use colors\n            --no-colors | --nocolors | --no-colour | --nocolour)\n                COLORS=0\n                RemoveColors\n            ;;\n\n            # Disable logging\n            --no-log | --nolog)\n                LOGFILE=\"/dev/null\"\n            ;;\n\n            # Skip execution of plugins\n            --no-plugins | --noplugins | --skip-plugins)\n                SKIP_PLUGINS=1\n            ;;\n\n            --pen-test | --pentest)\n                PENTESTINGMODE=1\n            ;;\n\n            # Define a custom profile file\n            --profile)\n                if [ $# -gt 1 ]; then\n                    shift\n                    SEARCH_PROFILES=\"$1\"\n                else\n                    echo \"Specify the profile (lynis audit system --profile /home/michael/myprofile.prf)\"\n                    exit 1\n                fi\n            ;;\n\n            # Define a custom plugin directory\n            --plugindir | --plugin-dir | --plugins-dir)\n                if [ $# -gt 1 ]; then\n                    shift\n                    PLUGINDIR=$1\n                    LASTCHAR=$(echo $1 | awk '{ print substr($0, length($0))}')\n                    if [ \"${LASTCHAR}\" = \"/\" ]; then\n                        echo \"${RED}Error:${WHITE} plugin directory path should not end with a slash${NORMAL}\"\n                        ExitCustom 65\n                    fi\n                    if [ ! -d ${PLUGINDIR} ]; then\n                        echo \"${RED}Error:${WHITE} invalid plugin directory ${PLUGINDIR}${NORMAL}\"\n                        ExitCustom 66\n                    fi\n                else\n                    echo \"Specify the plugin directory (lynis audit system --plugindir /home/michael/plugins)\"\n                    exit 1\n                fi\n            ;;\n\n            # Quiet mode\n            --quiet | -q | --silent)\n                QUIET=1\n            ;;\n\n            # Non-interactive mode\n            --quick | -Q)\n                QUICKMODE=1\n            ;;\n\n            # Define alternative report file\n            --report-file)\n                shift\n                REPORTFILE=$1\n            ;;\n\n            # Strip the colors which aren't clearly visible on light backgrounds\n            --reverse-colors | --reverse-colour)\n                BLUE=\"${NORMAL}\";\n                SECTION=\"${NORMAL}\";\n                NOTICE=\"${NORMAL}\";\n                CYAN=\"${NORMAL}\";\n                GREEN=\"${NORMAL}\";\n                YELLOW=\"${NORMAL}\";\n                WHITE=\"${NORMAL}\";\n                PURPLE=\"${NORMAL}\";\n            ;;\n\n            # Root directory (useful for forensics)\n            --rootdir | --root-dir)\n                if [ $# -gt 1 ]; then\n                    shift\n                    if [ -d $1 ]; then\n                        ROOTDIR=\"$1\"\n                    else\n                        echo \"Invalid rootdir provided (does not exist)\"\n                        exit 1\n                    fi\n                else\n                    echo \"Need a root directory (e.g. /mnt/forensics)\"\n                    exit 1\n                fi\n            ;;\n\n            # Only scan these tests\n            --tests)\n                shift\n                TESTS_TO_PERFORM=$1\n            ;;\n\n            # Scan one or more tests from just one category (e.g. security)\n            --tests-from-category)\n                shift\n                TEST_CATEGORY_TO_CHECK=$1\n            ;;\n\n            # Scan one or more tests from just on group\n            --tests-from-group | --tests-from-groups | --test-from-group | --test-from-groups)\n                shift\n                TEST_GROUP_TO_CHECK=$1\n            ;;\n\n            # Lynis Enterprise: upload data to central node\n            --upload)\n                UPLOAD_DATA=1\n            ;;\n\n            --usecwd | --use-cwd)\n                USE_CWD=1\n            ;;\n\n            --verbose)\n                VERBOSE=1\n            ;;\n\n            # Version number\n            --version | -V)\n                echo \"${PROGRAM_VERSION}\"\n                exit 0\n            ;;\n\n            # View man page\n            --view-manpage | --man-page | --manpage | --man)\n                if [ -f lynis.8 ]; then\n                    nroff -man lynis.8\n                    exit 0\n                else\n                    echo \"Error: man page file not found (lynis.8)\"\n                    echo \"If you are running an installed version of Lynis, use 'man lynis'\"\n                    exit 1\n                fi\n            ;;\n\n            --wait)\n                QUICKMODE=0\n            ;;\n\n            # Warnings\n            --warnings-only | --show-warnings-only)\n                SHOW_WARNINGS_ONLY=1\n                QUIET=1\n            ;;\n\n            # Warning when test is slow\n            --slow-warning)\n                if [ $# -gt 1 ]; then\n                    shift\n\n                    if [ \"$1\" -gt 0 ] 2>/dev/null; then\n                        SLOW_TEST_THRESHOLD=\"$1\"\n                    else\n                        echo \"Argument has to be number.\"\n                        exit 1\n                    fi\n                else\n                    echo \"Specify threshold as number of seconds above which should Lynis warn about long test.\"\n                    exit 1\n                fi\n            ;;\n\n            --tests-category | --tests-categories | --view-categories | --list-categories | --show-categories)\n                echo \"Error: Deprecated option ($1)\"\n                exit 1\n            ;;\n\n            # Soon to be deprecated options\n\n            # Perform tests (deprecated, use audit system)\n            --check-all | --checkall | -c)\n                echo \"This option (-c) is deprecated.\"\n                echo \"Use: lynis audit system [options]\"\n                ExitFatal\n            ;;\n\n            # View program/database information\n            --check-update | --check-updates | --info)\n                echo \"This option (--info) is deprecated\"\n                echo \"Use: lynis update info\"\n                ExitFatal\n            ;;\n\n            # Display all available options with short alias\n            --dump-options | --dumpoptions)\n                echo \"This option (--dump-options) is deprecated\"\n                echo \"Use: lynis show options\"\n                ExitFatal\n            ;;\n\n            # License key for Lynis Enterprise\n            --license-key)\n                echo \"This option is deprecated\"\n                echo \"Define a license key in /etc/lynis/custom.prf\"\n                ExitFatal\n            ;;\n\n\n            # Drop out when using wrong option(s)\n            *)\n                # Wrong option used, we bail out later\n                WRONGOPTION=1\n                WRONGOPTION_value=$1\n            ;;\n\n        esac\n        shift\n\n    done\n\n    # Ensure non-interactive mode when running quietly or as cronjob\n    if [ ${CRONJOB} -eq 1 -o ${QUIET} -eq 1 ]; then\n        if [ ${QUICKMODE} -eq 0 ]; then\n            if [ ${QUIET} -eq 0 ]; then\n                echo \"Switched back to quick mode (cron/non-interactive/quiet)\"\n            fi\n            QUICKMODE=1\n        fi\n    fi\n\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/profiles",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Read profile/template\n#\n#################################################################################\n#\n    # Set default values (should be equal to default.prf)\n    SETTING_LOG_TESTS_INCORRECT_OS=1\n    SETTING_SHOW_REPORT_SOLUTION=0\n    DEPRECATED_OPTION=\"\"\n#\n#################################################################################\n#\n    for PROFILE in ${PROFILES}; do\n\n        LogText \"Reading profile/configuration ${PROFILE}\"\n\n        # Show deprecation message for old config entries such as 'config:' and 'apache:'\n        FOUND=0\n        DATA=$(grep -E \"^[a-z-]{1,}:\" ${PROFILE})\n        if ! IsEmpty \"${DATA}\"; then FOUND=1; fi\n\n        if [ ${FOUND} -eq 1 ]; then\n            Display --text \" \"\n            Display --text \"==================================================================================================\"\n            DisplayWarning \"Your profile contains old-style configuration entries. See log file for more details and how to convert these entries\"\n            Display --indent 2 --text \"* ${RED}ISSUE${NORMAL}\"\n            Display --indent 2 --text \"Your profile has one or more lines that are in an old format (key:value). They need to be converted into the new format (key=value) or disabled.\"\n            Display --text \" \"\n            Display --indent 2 --text \"* ${GREEN}HOW TO RESOLVE${NORMAL}\"\n            Display --indent 2 --text \"Use grep to see the relevant matches (grep -E \\\"^[a-z-]{1,}:\\\" custom.prf)\"\n            Display --text \" \"\n            Display --text \"==================================================================================================\"\n            Display --text \" \"\n            LogText \"Insight: Profile '${PROFILE}' contains one or more old-style configuration entries\"\n            ReportWarning \"GEN-0020\" \"Your profile contains one or more old-style configuration entries\"\n            sleep 10\n        fi\n\n        # Security check for unexpected and possibly harmful escape characters (hyphen should be listed as first or last character)\n        DATA=$(grep -Ev '^$|^ |^#|^config:' \"${PROFILE}\" | tr -d '[a-zA-Z0-9]/\\[\\]\\(\\)_\\|,\\.:;= \\n\\r-')\n        if ! IsEmpty \"${DATA}\"; then\n            DisplayWarning \"Your profile '${PROFILE}' contains unexpected characters. See the log file for more information.\"\n            LogText \"Found unexpected or possibly harmful characters in profile '${PROFILE}'. See which characters matched in the output below and compare them with your profile.\"\n            for I in $(printf ${DATA} | od -An -ta); do\n                LogText \"Output: ${I}\"\n            done\n            LogText \"Suggestion: comment incorrect lines with a '#' and try again. Open a GitHub issue if valid characters are blocked\"\n            ExitFatal \"unexpected characters in profile. Stopping execution (security measure)\"\n        fi\n\n        # Now parse the profile and filter out unwanted characters\n        DATA=$(grep -E \"^config:|^[a-z-].*=\" ${PROFILE} | tr -dc '[a-zA-Z0-9]/\\[\\]\\(\\)_\\|,\\.:;= \\n\\r-' | sed 's/ /!space!/g')\n        for CONFIGOPTION in ${DATA}; do\n            if ContainsString \"^config:\" \"${CONFIGOPTION}\"; then\n                # Old style configuration\n                OPTION=$(echo ${CONFIGOPTION} | cut -d ':' -f2)\n                VALUE=$(echo ${CONFIGOPTION} | cut -d ':' -f3 | sed 's/!space!/ /g')\n                DEPRECATED_OPTION=\"${OPTION}\"\n            else\n                OPTION=$(echo ${CONFIGOPTION} | cut -d '=' -f1)\n                VALUE=$(echo ${CONFIGOPTION} | cut -d '=' -f2 | sed 's/!space!/ /g')\n            fi\n            Debug \"Profile option set: ${OPTION} (with value ${VALUE})\"\n\n            case ${OPTION} in\n\n                # Is Lynis Enterprise allowed to purge this system when it is becomes outdated?\n                allow-auto-purge)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)$\")\n                    if [ -n \"${FIND}\" ]; then\n                        Report \"allow-auto-purge=1\"\n                    else\n                        Report \"allow-auto-purge=0\"\n                    fi\n                ;;\n\n                # Define which compliance standards are enabled\n                # For this to work, the Enterprise plugins are needed\n                compliance_standards | compliance-standards | check-compliance)  # deprecated: compliance_standards\n                    COMPLIANCE_STANDARDS_ENABLED=$(echo ${VALUE} | tr ',' ' ')\n                    for STANDARD in ${COMPLIANCE_STANDARDS_ENABLED}; do\n                        case ${STANDARD} in\n                            cis)      COMPLIANCE_ENABLE_CIS=1      ; Debug \"Compliance scanning for CIS Benchmarks is enabled\" ;;\n                            hipaa)    COMPLIANCE_ENABLE_HIPAA=1    ; Debug \"Compliance scanning for HIPAA is enabled\" ;;\n                            iso27001) COMPLIANCE_ENABLE_ISO27001=1 ; Debug \"Compliance scanning for ISO27001 is enabled\" ;;\n                            pci-dss)  COMPLIANCE_ENABLE_PCI_DSS=1  ; Debug \"Compliance scanning for PCI DSS is enabled\" ;;\n                            *) LogText \"Result: Unknown compliance standard configured\" ;;\n                        esac\n                    done\n                ;;\n\n                # Check for a specific value\n                check-value)\n                    STRING=$(echo ${VALUE} | tr -d \"[\" | tr -d \"]\" | sed \"s/, /,/g\")\n                    CHECK_VALUE_ARRAY=\"${CHECK_OPTION_ARRAY} ${STRING}\"\n                ;;\n\n                # Colored output\n                colors)\n                    # Quick mode (SKIP_PLUGINS) might already be set outside profile, so store in different variable\n                    SETTING_COLORS=1 # default is yes\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(0|false|no)$\") && COLORS=0\n                    if [ -n \"${FIND}\" ]; then SETTING_COLORS=0; RemoveColors; fi\n                    Debug \"Colors set to ${SETTING_COLORS}\"\n                    AddSetting \"colors\" \"${SETTING_COLORS}\" \"Colored screen output\"\n                    unset SETTING_COLORS\n                ;;\n\n                # Ignore configuration data\n                config-data | permdir | permfile)\n                    Debug \"Ignoring configuration option, as it will be used by a specific test\"\n                ;;\n\n                # Maximum number of WAITing connections\n                connections-max-wait-state | connections_max_wait_state)\n                    OPTIONS_CONN_MAX_WAIT_STATE=\"${VALUE}\"\n                    AddSetting \"connections-max-wait-state\" \"${OPTIONS_CONN_MAX_WAIT_STATE}\" \"Connections (max-wait-state)\"\n                ;;\n\n                # Append something to URL for control information\n                control-url-append | control_url_append)\n                    CONTROL_URL_APPEND=\"${VALUE}\"\n                    AddSetting \"control-url-append\" \"${CONTROL_URL_APPEND}\" \"Control URL (append)\"\n                ;;\n\n                # Prepend an URL before control information link\n                control-url-prepend | control_url_prepend)\n                    CONTROL_URL_PREPEND=\"${VALUE}\"\n                    AddSetting \"control-url-prepend\" \"${CONTROL_URL_PREPEND}\" \"Control URL (prepend)\"\n                ;;\n\n                # Protocol to use for control information link\n                control-url-protocol | control_url_protocol)\n                    CONTROL_URL_PROTOCOL=\"${VALUE}\"\n                    AddSetting \"control-url-protocol\" \"${CONTROL_URL_PREPEND}\" \"Control URL (protocol)\"\n                ;;\n\n                # Append something to URL for control information (only applies to CUST-*)\n                custom-url-append | custom_url_append)\n                    CUSTOM_URL_APPEND=\"${VALUE}\"\n                    AddSetting \"custom-url-append\" \"${CUSTOM_URL_APPEND}\" \"Custom URL (append)\"\n                ;;\n\n                # Prepend an URL before control information link (only applies to CUST-*)\n                custom-url-prepend | custom_url_prepend)\n                    CUSTOM_URL_PREPEND=\"${VALUE}\"\n                    AddSetting \"custom-url-prepend\" \"${CUSTOM_URL_PREPEND}\" \"Custom URL (prepend)\"\n                ;;\n\n                # Protocol to use for control information link\n                custom-url-protocol | custom_url_protocol)\n                    CUSTOM_URL_PROTOCOL=\"${VALUE}\"\n                    AddSetting \"custom-url-protocol\" \"${CUSTOM_URL_PREPEND}\" \"Custom URL (protocol)\"\n                ;;\n\n                # Do not check security repository in sources.list (Debian/Ubuntu)\n                debian-skip-security-repository | debian_skip_security_repository)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && OPTION_DEBIAN_SKIP_SECURITY_REPOSITORY=1 \n                    AddSetting \"debian-skip-security-repository\" \"OPTION_DEBIAN_SKIP_SECURITY_REPOSITORY\" \"Skip checking for a security repository (Debian and others)\"\n                ;;\n\n                # Debug status to show more details while running program\n                debug)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && DEBUG=1\n                    Debug \"Debug mode set to '${DEBUG}'\"\n                    AddSetting \"debug\" \"${DEBUG}\" \"Debugging mode\"\n                ;;\n\n                # Development mode (--developer)\n                developer-mode)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && DEVELOPER_MODE=1\n                    Debug \"Developer mode set to ${DEVELOPER_MODE}\"\n                    AddSetting \"developer\" \"${DEVELOPER_MODE}\" \"Developer mode\"\n                ;;\n\n                # Show non-zero exit code when errors are found\n                error-on-warnings)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && ERROR_ON_WARNINGS=1\n                    Debug \"Exit with different code on warnings is set to ${ERROR_ON_WARNINGS}\"\n                    AddSetting \"error-on-warnings\" \"${ERROR_ON_WARNINGS}\" \"Use non-zero exit code if one or more warnings were found\"\n                ;;\n\n                # Skip FreeBSD port audit\n                freebsd-skip-portaudit | freebsd_skip_portaudit)\n                    LogText \"Option set: Skip FreeBSD portaudit\"\n                    OPTION_FREEBSD_SKIP_PORTAUDIT=\"${VALUE}\"\n                ;;\n\n                # Lynis Enterprise: group name - deprecated option\n                group)\n                    GROUP_NAME=\"${VALUE}\"\n                    AddSetting \"group\" \"${GROUP_NAME}\" \"Group\"\n                    DEPRECATED_OPTION=\"group\"\n                ;;\n\n                hostalias | host-alias)\n                    if [ -n \"${VALUE}\" ]; then Report \"hostname_alias=${VALUE}\"; fi\n                ;;\n\n                hostid)\n                    HOSTID=\"${VALUE}\"\n                ;;\n\n                hostid2)\n                    HOSTID2=\"${VALUE}\"\n                ;;\n\n                # Home directories to ignore during scans\n                ignore-home-dir)\n                    Report \"ignore-home-dir[]=${VALUE}\"\n                ;;\n\n                # Language\n                language | lang)\n                    LogText \"Language set via profile to '${VALUE}'\"\n                    if [ -n \"${VALUE}\" ]; then LANGUAGE=\"${VALUE}\"; fi\n                    AddSetting \"language\" \"${LANGUAGE}\" \"Language\"\n                ;;\n\n                # Lynis Enterprise license key\n                license-key | license_key)\n                    if [ -n \"${VALUE}\" ]; then\n                        LICENSE_KEY=\"${VALUE}\"\n                        Report \"license_key=${VALUE}\"\n                    fi\n                    AddSetting \"license-key\" \"${VALUE}\" \"License key\"\n                ;;\n\n                # Do (not) log tests if they have an different operating system\n                log-tests-incorrect-os | log_tests_incorrect_os)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(0|false|no)\") && SETTING_LOG_TESTS_INCORRECT_OS=0\n                    Debug \"Logging of tests with incorrect operating system set to ${SETTING_LOG_TESTS_INCORRECT_OS}\"\n                    LOG_INCORRECT_OS=${SETTING_LOG_TESTS_INCORRECT_OS}\n                ;;\n\n                # What type of machine we are scanning (eg. personal, workstation or server)\n                machine-role | machine_role)\n                    MACHINE_ROLE=\"${VALUE}\"\n                    AddSetting \"machine-role\" \"${MACHINE_ROLE}\" \"Machine role (personal, workstation or server)\"\n                ;;\n\n                # Define if any found NTP daemon instance is configured as a server or client\n                ntpd-role | ntpd_role)\n                    NTPD_ROLE=\"${VALUE}\"\n                    AddSetting \"ntpd-role\" \"${NTPD_ROLE}\" \"NTP role (server or client)\"\n                ;;\n\n                # How much seconds to wait between tests\n                pause_between_tests | pause-between-tests)\n                    TEST_PAUSE_TIME=\"${VALUE}\"\n                    AddSetting \"pause-between-tests\" \"${TEST_PAUSE_TIME}\" \"Pause between tests (in seconds)\"\n                ;;\n\n                # Plugin\n                plugin)\n                    LogText \"Plugin '${VALUE}' enabled according profile (${PROFILE})\"\n                ;;\n\n                disable-plugin)\n                    LogText \"Plugin '${VALUE}' disabled according profile (${PROFILE})\"\n                    DISABLED_PLUGINS=\"${DISABLED_PLUGINS} ${VALUE}\"\n                ;;\n\n                # Plugin directory\n                plugindir | plugin-dir)\n                    if IsEmpty \"${PLUGINDIR}\"; then\n                        PLUGINDIR=\"${VALUE}\"\n                    else\n                        LogText \"Plugin directory was already set to ${PLUGINDIR} before (most likely as a program argument), not overwriting\"\n                    fi\n                    AddSetting \"plugin-dir\" \"${PLUGINDIR}\" \"Plugin directory\"\n                ;;\n\n                # Profile name\n                profile-name | profile_name)\n                    PROFILE_NAME=\"${VALUE}\"\n                ;;\n\n                # Quick (no waiting for keypresses)\n                quick)\n                    # Quick mode might already be set outside profile, so store in different variable\n                    SETTING_QUICK_MODE=1 # default is yes\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(0|false|no)$\") && QUICKMODE=0\n                    if [ -n \"${FIND}\" ]; then SETTING_QUICK_MODE=1; fi\n                    Debug \"Quickmode set to ${SETTING_QUICK_MODE}\"\n                    AddSetting \"quick\" \"${SETTING_QUICK_MODE}\" \"Quick mode (non-interactive)\"\n                ;;\n\n                # Refresh software repositories\n                refresh-repositories)\n                    SETTING_REFRESH_REPOSITORIES=1 # default is yes\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(0|false|no)$\") && REFRESH_REPOSITORIES=0\n                    if [ -n \"${FIND}\" ]; then SETTING_REFRESH_REPOSITORIES=0; fi\n                    Debug \"Refreshing repositories set to ${SETTING_REFRESH_REPOSITORIES}\"\n                    AddSetting \"refresh-repositories\" \"${SETTING_REFRESH_REPOSITORIES}\" \"Refresh repositories (for vulnerable package detection)\"\n                ;;\n\n                # Show more details in report\n                show-report-solution)\n                    SETTING_SHOW_REPORT_SOLUTION=${SHOW_REPORT_SOLUTION}\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(0|false|no)$\") && SHOW_REPORT_SOLUTION=0\n                    if [ -n \"${FIND}\" ]; then SETTING_SHOW_REPORT_SOLUTION=0; fi\n                    Debug \"Show report details (solution) set to ${SETTING_SHOW_REPORT_SOLUTION}\"\n                ;;\n\n                # Inline tips about tool (default enabled)\n                show_tool_tips | show-tool-tips)\n                    SETTING_SHOW_TOOL_TIPS=1 # default is yes\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(0|false|no)$\") && SHOW_TOOL_TIPS=0\n                    if [ -n \"${FIND}\" ]; then SETTING_SHOW_TOOL_TIPS=0; fi\n                    Debug \"Show tool tips set to ${SETTING_SHOW_TOOL_TIPS}\"\n                    AddSetting \"show-tool-tips\" \"${SETTING_SHOW_TOOL_TIPS}\" \"Show tool tips\"\n                ;;\n\n                # Show warnings only\n                show-warnings-only)\n                    QUIET=1\n                    QUICKMODE=1\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)$\") && SHOW_WARNINGS_ONLY=1\n                    Debug \"Show warnings only set to ${SHOW_WARNINGS_ONLY}\"\n                    AddSetting \"show-warnings-only\" \"${SHOW_WARNINGS_ONLY}\" \"Show only warnings\"\n                ;;\n\n                # Skip plugins\n                skip-plugins)\n                    # Skip plugins (SKIP_PLUGINS) might already be set, so store in different variable\n                    SETTING_SKIP_PLUGINS=0 # default is no\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)$\") && SKIP_PLUGINS=1\n                    if [ -n \"${FIND}\" ]; then SETTING_SKIP_PLUGINS=1; fi\n                    Debug \"Skip plugins is set to ${SETTING_SKIP_PLUGINS}\"\n                    AddSetting \"skip-plugins\" \"${SETTING_SKIP_PLUGINS}\" \"Skip plugins\"\n                ;;\n\n                # Which tests to skip (skip-test=ABCD-1234 or skip-test=ABCD-1234:subtest)\n                skip-test)\n                    STRING=$(echo ${VALUE} | awk '{print toupper($0)}')\n                    SKIP_TESTS=\"${SKIP_TESTS} ${STRING}\"\n                ;;\n\n                # Do not check the latest version on the internet\n                skip_upgrade_test | skip-upgrade-test)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && SKIP_UPGRADE_TEST=1\n                    Debug \"Skip upgrade test set to ${SKIP_UPGRADE_TEST}\"\n                ;;\n\n                # SSL paths\n                ssl-certificate-paths)\n                    SSL_CERTIFICATE_PATHS=\"${VALUE}\"\n                    Debug \"SSL paths set to ${SSL_CERTIFICATE_PATHS}\"\n                    AddSetting \"ssl-certificate-paths\" \"${SSL_CERTIFICATE_PATHS}\" \"Paths for SSL certificates\"\n                ;;\n\n                ssl-certificate-paths-to-ignore)\n                    # Retrieve paths to ignore when searching for certificates. Strip special characters, replace possible spaces\n                    SSL_CERTIFICATE_PATHS_TO_IGNORE=$(echo ${VALUE} | tr -d '[\\001-\\037]' | sed 's/ /__space__/g' | tr ':' ' ')\n                    Debug \"SSL paths to ignore: ${SSL_CERTIFICATE_PATHS_TO_IGNORE}\"\n                    AddSetting \"ssl-certificate-paths-to-ignore\" \"${SSL_CERTIFICATE_PATHS_TO_IGNORE}\" \"Paths that should be ignored for SSL certificates\"\n                ;;\n\n                # Check also certificates provided by packages?\n                ssl-certificate-include-packages)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && SSL_CERTIFICATE_INCLUDE_PACKAGES=1\n                    Debug \"Check also certificates provided by packages set to ${SSL_CERTIFICATE_INCLUDE_PACKAGES}\"\n                ;;\n\n\n                # Set strict mode for development and quality purposes\n                strict)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && SET_STRICT=1\n                ;;\n\n                # The name of the customer/client that uses this system\n                system-customer-name)\n                    if [ -n \"${VALUE}\" ]; then Report \"system-customer-name=${VALUE}\"; fi\n                ;;\n\n                # The groups linked to a system (system-groups=customers,webservers,production)\n                system-groups)\n                    if [ -n \"${VALUE}\" ]; then Report \"system-groups=${VALUE}\"; fi\n                ;;\n\n                # Tags (tags=db,production,ssn-1304)\n                tags)\n                    if [ -n \"${VALUE}\" ]; then Report \"tags=${VALUE}\"; fi\n                ;;\n\n                # Define what kind of scan we are performing\n                test_scan_mode | test-scan-mode)\n                    if [ \"${VALUE}\" = \"light\" ]; then   SCAN_TEST_LIGHT=\"YES\"; SCAN_TEST_MEDIUM=\"NO\";  SCAN_TEST_HEAVY=\"NO\";  fi\n                    if [ \"${VALUE}\" = \"normal\" ]; then  SCAN_TEST_LIGHT=\"YES\"; SCAN_TEST_MEDIUM=\"YES\"; SCAN_TEST_HEAVY=\"NO\";  fi\n                    if [ \"${VALUE}\" = \"full\" ]; then    SCAN_TEST_LIGHT=\"YES\"; SCAN_TEST_MEDIUM=\"YES\"; SCAN_TEST_HEAVY=\"YES\"; fi\n                    AddSetting \"test-scan-mode\" \"${VALUE}\" \"Scan mode\"\n                ;;\n\n                # Perform upload\n                upload)\n                    SETTING_UPLOAD=no # default\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)$\") && UPLOAD_DATA=1\n                    if [ -n \"${FIND}\" ]; then SETTING_UPLOAD=1; fi\n                    Debug \"Upload set to ${SETTING_UPLOAD}\"\n                    AddSetting \"upload\" \"${SETTING_UPLOAD}\" \"Data upload after scanning\"\n                    unset SETTING_UPLOAD\n                ;;\n\n\n                # Compression of uploads (enabled by default)\n                upload_compressed | compressed-uploads)\n                    if [ \"${VALUE}\" = \"0\" ]; then COMPRESSED_UPLOADS=0; fi\n                    AddSetting \"compressed-uploads\" \"${COMPRESSED_UPLOADS}\" \"Compressed uploads\"\n                ;;\n\n                # Options during upload of data\n                upload_options | upload-options)\n                    UPLOAD_OPTIONS=\"${VALUE}\"\n                    AddSetting \"upload-options\" \"${UPLOAD_OPTIONS}\" \"Upload options\"\n                ;;\n\n                # Proxy settings\n                upload_proxy_port | proxy-port | upload-proxy-port)\n                    UPLOAD_PROXY_PORT=\"${VALUE}\"\n                    AddSetting \"upload-proxy-port\" \"${UPLOAD_PROXY_PORT}\" \"Proxy port\"\n                ;;\n                upload_proxy_protocol | proxy-protocol)\n                    UPLOAD_PROXY_PROTOCOL=\"${VALUE}\"\n                    AddSetting \"upload-proxy-protocol\" \"${UPLOAD_PROXY_PROTOCOL}\" \"Proxy protocol\"\n                ;;\n                upload_proxy_server | proxy-server)\n                    UPLOAD_PROXY_SERVER=\"${VALUE}\"\n                    AddSetting \"upload-proxy-server\" \"${UPLOAD_PROXY_PORT}\" \"Proxy server\"\n                ;;\n\n                # Receiving system (IP address or hostname)\n                upload-server)\n                    UPLOAD_SERVER=\"${VALUE}\"\n                    AddSetting \"upload-server\" \"${UPLOAD_SERVER}\" \"Upload server (ip or hostname)\"\n                ;;\n\n                # Specify an alternative upload tool\n                upload-tool)\n                    if [ -f \"${VALUE}\" ]; then UPLOAD_TOOL=\"${VALUE}\"; fi\n                    AddSetting \"upload-tool\" \"${UPLOAD_TOOL}\" \"Upload tool\"\n                ;;\n\n                # Specify arguments for an alternative upload tool\n                upload-tool-arguments)\n                    UPLOAD_TOOL_ARGS=\"${VALUE}\"\n                    AddSetting \"upload-tool-arguments\" \"${UPLOAD_TOOL_ARGS}\" \"Upload tool (arguments)\"\n                ;;\n\n                # Verbose output (--verbose)\n                verbose)\n                    FIND=$(echo \"${VALUE}\" | grep -E \"^(1|true|yes)\") && VERBOSE=1\n                    Debug \"Verbose set to ${VERBOSE}\"\n                    AddSetting \"verbose\" \"${VERBOSE}\" \"Verbose output\"\n                ;;\n\n                ########################################################################################################\n                ## DEPRECATED ITEMS\n                ########################################################################################################\n\n                # Deprecated: skip tests\n                test_skip_always)\n                    STRING=$(echo ${VALUE} | awk '{print toupper($0)}')\n                    SKIP_TESTS=\"${SKIP_TESTS} ${STRING}\"\n                    LogText \"[deprecated option] Tests to be skipped: ${VALUE}\"\n                    DisplayToolTip \"Replace deprecated option 'test_skip_always' and replace with 'skip-test' (add to custom.prf)\"\n                ;;\n\n                # Deprecated: receiving system (IP address or hostname)\n                upload_server)\n                    UPLOAD_SERVER=\"${VALUE}\"\n                    AddSetting \"upload-server\" \"${UPLOAD_SERVER}\" \"Upload server (ip or hostname)\"\n                    DisplayToolTip \"Replace deprecated option 'upload_server' and replace with 'upload-server' (add to custom.prf)\"\n                ;;\n\n\n                # Catch all bad options and bail out\n                *)\n                    LogText \"Unknown option ${OPTION} (with value: ${VALUE})\"\n\n                    ${ECHOCMD:-echo} \"\"\n                    ${ECHOCMD:-echo} \"${RED}Error${NORMAL}: found one or more errors in profile ${PROFILE}\"\n                    ${ECHOCMD:-echo} \"\"\n                    ${ECHOCMD:-echo} \"\"\n                    ${ECHOCMD:-echo} \"Full line: ${CONFIGOPTION}\"\n                    ${ECHOCMD:-echo} \"${WHITE}Details${NORMAL}: Unknown option '${YELLOW}${OPTION}${NORMAL}' found (with value: ${VALUE})\"\n                    ${ECHOCMD:-echo} \"\"\n                    ExitFatal\n                ;;\n\n            esac\n\n        done\n    done\n#\n#################################################################################\n#\n    SKIP_TESTS=$(echo ${SKIP_TESTS} | sed \"s/^ //\")\n    if [ -n \"${SKIP_TESTS}\" ]; then LogText \"Skip tests: ${SKIP_TESTS}\"; fi\n#\n#################################################################################\n#\n    # Add group name to report - deprecated\n    if [ -n \"${GROUP_NAME}\" ]; then Report \"group=${GROUP_NAME}\"; fi\n#\n#################################################################################\n#\n    # Set default values (only if not configured in profile)\n    if [ -z \"${MACHINE_ROLE}\" ]; then\n        MACHINE_ROLE=\"server\"\n        LogText \"Set option to default value: MACHINE_ROLE --> ${MACHINE_ROLE}\"\n    fi\n\n    if [ -z \"${NTPD_ROLE}\" ]; then\n        NTPD_ROLE=\"client\"\n        LogText \"Set option to default value: NTPD_ROLE --> ${NTPD_ROLE}\"\n    fi\n#\n#################################################################################\n#\n    # Register the discovered settings\n    AddSetting \"log-tests-incorrect-os\" \"${SETTING_LOG_TESTS_INCORRECT_OS}\" \"Logging of tests that have a different OS\"\n    AddSetting \"show-report-solution\" \"${SETTING_SHOW_REPORT_SOLUTION}\" \"Show more details in report (solution)\"\n    AddSetting \"skip-upgrade-test\" \"${SKIP_UPGRADE_TEST}\" \"Skip upgrade test\"\n    AddSetting \"strict\" \"${SET_STRICT}\" \"Perform strict code test of scripts\"\n\n    unset SETTING_LOG_TESTS_INCORRECT_OS SETTING_SHOW_REPORT_SOLUTION\n#\n#################################################################################\n#\n    if [ -n \"${DEPRECATED_OPTION}\" ]; then\n        ReportWarning \"GEN-0030\" \"One or more deprecated options used in profile\" \"${DEPRECATED_OPTION}\" \"Update your profile\"\n    fi\n#\n#################################################################################\n#\n\n    Display --indent 2 --text \"- Checking profiles...\" --result \"DONE\" --color GREEN\n\n\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/report",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Report\n#\n#################################################################################\n#\n    # Add additional data fields to the report file at the end of the scan\n    Report \"dhcp_client_running=${DHCP_CLIENT_RUNNING}\"\n    Report \"arpwatch_running=${ARPWATCH_RUNNING}\"\n\n    # Report firewall installed for now, if we found one active. Next step would be determining binaries first and apply additional checks.\n    Report \"firewall_active=${FIREWALL_ACTIVE}\"\n    Report \"firewall_empty_ruleset=${FIREWALL_EMPTY_RULESET}\"\n    Report \"firewall_installed=${FIREWALL_ACTIVE}\"\n\n    if [ -n \"${INSTALLED_PACKAGES}\" ]; then Report \"installed_packages_array=${INSTALLED_PACKAGES}\"; fi\n\n    Report \"package_audit_tool=${PACKAGE_AUDIT_TOOL}\"\n    Report \"package_audit_tool_found=${PACKAGE_AUDIT_TOOL_FOUND}\"\n    Report \"vulnerable_packages_found=${VULNERABLE_PACKAGES_FOUND}\"\n#\n#################################################################################\n#\n    # Hardening Index\n    #\n    # Goal:\n    # Provide a visual way to show how much the system is hardened\n    #\n    # Important:\n    # The index gives a simplified version of the measures taken on the system.\n    # It should be used to get a first impression about the state of the system or to compare similar systems.\n    # Getting the maximum score (100 or full bar) does not indicate that the system is fully secured.\n\n    # If no hardening has been found, set value to 1\n    if [ ${HPPOINTS} -eq 0 ]; then HPPOINTS=1; HPTOTAL=100; fi\n    HPINDEX=$((HPPOINTS * 100 / HPTOTAL))\n    HPAOBLOCKS=$((HPPOINTS * 20 / HPTOTAL))\n    # Set color related to rating\n    if [ ${HPINDEX} -lt 50 ]; then\n        HPCOLOR=\"${RED}\"\n        HIDESCRIPTION=\"System has not or a low amount been hardened\"\n    elif [ ${HPINDEX} -gt 49 -a ${HPINDEX} -lt 80 ]; then\n        HPCOLOR=\"${YELLOW}\"\n        HIDESCRIPTION=\"System has been hardened, but could use additional hardening\"\n    elif [ ${HPINDEX} -gt 79 -a ${HPINDEX} -lt 90 ]; then\n        HPCOLOR=\"${GREEN}\"\n        HIDESCRIPTION=\"System seem to be decent hardened\"\n    elif [ ${HPINDEX} -gt 89 ]; then\n        HPCOLOR=\"${GREEN}\"\n        HIDESCRIPTION=\"System seem to be well hardened\"\n    fi\n\n    case ${HPAOBLOCKS} in\n        0)  HPBLOCKS=\"#\"; HPEMPTY=\"                   \" ;;\n        1)  HPBLOCKS=\"#\"; HPEMPTY=\"                   \" ;;\n        2)  HPBLOCKS=\"##\"; HPEMPTY=\"                  \" ;;\n        3)  HPBLOCKS=\"###\"; HPEMPTY=\"                 \" ;;\n        4)  HPBLOCKS=\"####\"; HPEMPTY=\"                \" ;;\n        5)  HPBLOCKS=\"#####\"; HPEMPTY=\"               \" ;;\n        6)  HPBLOCKS=\"######\"; HPEMPTY=\"              \" ;;\n        7)  HPBLOCKS=\"#######\"; HPEMPTY=\"             \" ;;\n        8)  HPBLOCKS=\"########\"; HPEMPTY=\"            \" ;;\n        9)  HPBLOCKS=\"#########\"; HPEMPTY=\"           \" ;;\n        10) HPBLOCKS=\"##########\"; HPEMPTY=\"          \" ;;\n        11) HPBLOCKS=\"###########\"; HPEMPTY=\"         \" ;;\n        12) HPBLOCKS=\"############\"; HPEMPTY=\"        \" ;;\n        13) HPBLOCKS=\"#############\"; HPEMPTY=\"       \" ;;\n        14) HPBLOCKS=\"##############\"; HPEMPTY=\"      \" ;;\n        15) HPBLOCKS=\"###############\"; HPEMPTY=\"     \" ;;\n        16) HPBLOCKS=\"################\"; HPEMPTY=\"    \" ;;\n        17) HPBLOCKS=\"#################\"; HPEMPTY=\"   \" ;;\n        18) HPBLOCKS=\"##################\"; HPEMPTY=\"  \" ;;\n        19) HPBLOCKS=\"###################\"; HPEMPTY=\" \" ;;\n        20) HPBLOCKS=\"####################\"; HPEMPTY=\"\" ;;\n    esac\n\n    HPGRAPH=\"[${HPCOLOR}${HPBLOCKS}${NORMAL}${HPEMPTY}]\"\n    LogText \"Hardening index : [${HPINDEX}] [${HPBLOCKS}${HPEMPTY}]\"\n    LogText \"Hardening strength: ${HIDESCRIPTION}\"\n#\n#################################################################################\n#\n    # Only show overview if not running in quiet mode\n    if [ ${QUIET} -eq 0 ]; then\n        echo \"\"; echo \"================================================================================\"\n        echo \"\"; echo \"  -[ ${WHITE}${PROGRAM_NAME} ${PROGRAM_VERSION} Results${NORMAL} ]-\"\n        echo \"\";\n\n\n    if [ ${SHOW_REPORT} -eq 1 ]; then\n\n        LogTextBreak\n\n        # Show test results overview\n\n            if [ -z \"${CONTROL_URL_PROTOCOL}\" ]; then CONTROL_URL_PROTOCOL=\"https\"; fi\n            if [ -z \"${CONTROL_URL_PREPEND}\" ]; then CONTROL_URL_PREPEND=\"cisofy.com/lynis/controls/\"; fi\n            if [ -z \"${CONTROL_URL_APPEND}\" ]; then CONTROL_URL_APPEND=\"/\"; fi\n            if [ -z \"${CUSTOM_URL_PROTOCOL}\" ]; then CUSTOM_URL_PROTOCOL=\"https\"; fi\n            if [ -z \"${CUSTOM_URL_PREPEND}\" ]; then CUSTOM_URL_PREPEND=\"your-domain.example.org/controls/\"; fi\n            if [ -z \"${CUSTOM_URL_APPEND}\" ]; then CUSTOM_URL_APPEND=\"/\"; fi\n\n            # Show warnings from logfile\n            SWARNINGS=$(${GREPBINARY} 'Warning: ' ${LOGFILE} | sed 's/ /!space!/g')\n            if [ -z \"${SWARNINGS}\" ]; then\n                echo \"  ${OK}Great, no warnings${NORMAL}\"; echo \"\"\n            else\n                echo \"  ${WARNING}Warnings${NORMAL} (${TOTAL_WARNINGS}):\"\n                echo \"  ${WHITE}----------------------------${NORMAL}\"\n                for WARNING in ${SWARNINGS}; do\n                    SOLUTION=\"\"\n                    SHOWWARNING=$(echo ${WARNING} | sed 's/!space!/ /g' | sed 's/^.* Warning: //' | sed 's/\\[details:\\(.*\\)\\] \\[solution:\\(.*\\)\\]//' | sed 's/test://')\n                    ADDLINK=$(echo ${WARNING} | sed 's/!space!/ /g' | sed 's/^.* Warning: \\(.*\\)\\[test://' | sed 's/\\]\\(.*\\)]//' | ${AWKBINARY} -F: '{print $1}')\n                    DETAILS=$(echo ${WARNING} | sed 's/!space!/ /g' | sed 's/^.* Warning: \\(.*\\)\\[details://' | sed 's/\\]\\(.*\\)]//')\n                    SUGGESTION_PIECES=$(echo ${WARNING} | sed 's/\\[/ [/g')\n                    for PIECE in ${SUGGESTION_PIECES}; do\n                        if [ -z \"${SOLUTION}\" ]; then\n                            SEARCH=$(echo ${PIECE} | grep \"^\\[solution:\")\n                            if [ $? -eq 0 ]; then SOLUTION=$(echo ${SEARCH} | sed 's/!space!/ /g' | sed 's/solution://' | sed 's/text://' | tr -d '[]'); fi\n                        fi\n                    done\n                    IS_CUSTOM=$(echo ${ADDLINK} | grep \"^CUST\")\n                    echo \"  ${RED}!${NORMAL} ${SHOWWARNING}\"\n                    if [ ! \"${DETAILS}\" = \"-\" -a -n \"${DETAILS}\" ]; then echo \"    - Details  : ${CYAN}${DETAILS}${NORMAL}\"; fi\n                    if [ ${SHOW_REPORT_SOLUTION} -eq 1 -a ! \"${SOLUTION}\" = \"-\" ]; then echo \"    - Solution : ${SOLUTION}\"; fi\n                    if [ -z \"${IS_CUSTOM}\" ]; then\n                        echo \"      ${CONTROL_URL_PROTOCOL}://${CONTROL_URL_PREPEND}${ADDLINK}${CONTROL_URL_APPEND}\"\n                    else\n                        echo \"      ${CUSTOM_URL_PROTOCOL}://${CUSTOM_URL_PREPEND}${ADDLINK}${CUSTOM_URL_APPEND}\"\n                    fi\n                    echo \"\"\n                done\n            fi\n\n            # Show suggestions from logfile\n            SUGGESTIONS=$(${GREPBINARY} 'Suggestion: ' ${LOGFILE} | sed 's/ /!space!/g')\n\n            if [ -z \"${SUGGESTIONS}\" ]; then\n                echo \"  ${OK}No suggestions${NORMAL}\"; echo \"\"\n            else\n                echo \"  ${YELLOW}Suggestions${NORMAL} (${TOTAL_SUGGESTIONS}):\"\n                echo \"  ${WHITE}----------------------------${NORMAL}\"\n                for SUGGESTION in ${SUGGESTIONS}; do\n                    SOLUTION=\"\"\n                    SHOWSUGGESTION=$(echo ${SUGGESTION} | sed 's/!space!/ /g' | sed 's/^.* Suggestion: //' | sed 's/\\[details:\\(.*\\)\\] \\[solution:\\(.*\\)\\]//' | sed 's/test://')\n                    RELATED_CONTROL=$(echo ${SUGGESTION} | sed 's/!space!/ /g' | sed 's/^.* Suggestion: \\(.*\\)\\[test://' | sed 's/\\]\\(.*\\)]//' | ${AWKBINARY} -F: '{print $1}')\n                    ADDLINK=\"${RELATED_CONTROL}\"\n                    DETAILS=$(echo ${SUGGESTION} | sed 's/!space!/ /g' | sed 's/^.* Suggestion: \\(.*\\)\\[details://' | sed 's/\\]\\(.*\\)]//')\n                    SUGGESTION_PIECES=$(echo ${SUGGESTION} | sed 's/\\[/ [/g')\n                    for PIECE in ${SUGGESTION_PIECES}; do\n                        if [ -z \"${SOLUTION}\" ]; then\n                            SEARCH=$(echo ${PIECE} | grep \"^\\[solution:\")\n                            if [ $? -eq 0 ]; then SOLUTION=$(echo ${SEARCH} | sed 's/!space!/ /g' | sed 's/solution://' | sed 's/text://' | tr -d '[]'); fi\n                        fi\n                    done\n                    IS_CUSTOM=$(echo ${ADDLINK} | grep \"^CUST\")\n                    echo \"  ${YELLOW}*${NORMAL} ${SHOWSUGGESTION}\"\n                    if [ ! \"${DETAILS}\" = \"-\" -a -n \"${DETAILS}\" ]; then echo \"    - Details  : ${CYAN}${DETAILS}${NORMAL}\"; fi\n                    if [ ${SHOW_REPORT_SOLUTION} -eq 1 -a ! \"${SOLUTION}\" = \"-\" ]; then echo \"    - Solution : ${SOLUTION}\"; fi\n                    # Show relevant articles if the database is available\n                    if [ -f ${DBDIR}/control-links.db ]; then\n                        echo \"    - Related resources\"\n                        ARTICLES=$($AWKBINARY -F \\; -v control=${RELATED_CONTROL} '{if($1==control && $2==\"blog\"){print $2\";\"$3\";\"$4\";\"}}' \"${DBDIR}/control-links.db\" | sed 's/ /!space!/g')\n                        if [ -n \"${ARTICLES}\" ]; then\n                            for ITEM in ${ARTICLES}; do\n                                ITEM=$(echo ${ITEM} | sed 's/!space!/ /g')\n                                ARTICLE=$(echo ${ITEM} | awk -F\\; '{print $2}')\n                                ARTICLE_LINK=$(echo ${ITEM} | awk -F\\; '{print $3}')\n                                echo \"      * Article: ${CYAN}${ARTICLE}${NORMAL}: ${ARTICLE_LINK}\"\n                            done\n                        fi\n                    fi\n                    if [ -z \"${IS_CUSTOM}\" ]; then\n                        echo \"      * Website: ${GRAY}${CONTROL_URL_PROTOCOL}://${CONTROL_URL_PREPEND}${ADDLINK}${CONTROL_URL_APPEND}${NORMAL}\"\n                    else\n                        echo \"      * Details: ${GRAY}${CUSTOM_URL_PROTOCOL}://${CUSTOM_URL_PREPEND}${ADDLINK}${CUSTOM_URL_APPEND}${NORMAL}\"\n                    fi\n                    echo \"\"\n                done\n            fi\n            # Show tip on how to continue (next steps)\n            if [ ! \"${SWARNINGS}\" = \"\" -o ! \"${SUGGESTIONS}\" = \"\" ]; then\n                echo \"  ${CYAN}Follow-up${NORMAL}:\"\n                echo \"  ${WHITE}----------------------------${NORMAL}\"\n                echo \"  ${WHITE}-${NORMAL} Show details of a test (lynis show details TEST-ID)\"\n                echo \"  ${WHITE}-${NORMAL} Check the logfile for all details (less ${LOGFILE})\"\n                echo \"  ${WHITE}-${NORMAL} Read security controls texts (https://cisofy.com)\"\n                if [ ${UPLOAD_DATA} -eq 0 ]; then echo \"  ${WHITE}-${NORMAL} Use --upload to upload data to central system (Lynis Enterprise users)\"; fi\n                echo \"\"\n            fi\n            echo \"================================================================================\"\n            echo \"\"\n            echo \"  ${WHITE}Lynis security scan details${NORMAL}:\"\n            echo \"\"\n            echo \"  ${SECTION}Scan mode${NORMAL}:\"\n            if [ ${DEVOPS_MODE} -eq 1 ]; then\n                echo \"  Normal [ ]  Forensics [ ]  Integration [▆]  Pentest [ ]\"\n            elif [ ${FORENSICS_MODE} -eq 1 ]; then\n                echo \"  Normal [ ]  Forensics [▆]  Integration [ ]  Pentest [ ]\"\n            elif [ ${PENTESTINGMODE} -eq 1 ]; then\n                if [ ${PRIVILEGED} -eq 0 ]; then\n                    echo \"  Normal [ ]  Forensics [ ]  Integration [ ]  Pentest [▆] (running non-privileged)\"\n                else\n                    echo \"  Normal [ ]  Forensics [ ]  Integration [ ]  Pentest [▆] (running privileged)\"\n                fi\n            else\n                echo \"  Normal [▆]  Forensics [ ]  Integration [ ]  Pentest [ ]\"\n            fi\n            echo \"\"\n\n            echo \"  ${SECTION}Lynis modules${NORMAL}:\"\n            if [ ${COMPLIANCE_TESTS_PERFORMED} -eq 1 ]; then\n                if [ ${COMPLIANCE_FINDINGS_FOUND} -eq 0 ]; then COMPLIANCE=\"${GREEN}V\"; else COMPLIANCE=\"${RED}X\"; fi\n            else\n                COMPLIANCE=\"${YELLOW}?\"\n            fi\n            echo \"  - Compliance status      [${COMPLIANCE}${NORMAL}]\"\n            echo \"  - Security audit         [${GREEN}V${NORMAL}]\"\n            echo \"  - Vulnerability scan     [${GREEN}V${NORMAL}]\"\n            echo \"\"\n            echo \"  ${SECTION}Details${NORMAL}:\"\n            echo \"  ${CYAN}Hardening index${NORMAL} : ${WHITE}${HPINDEX}${NORMAL} ${HPGRAPH}\"\n            echo \"  ${CYAN}Tests performed${NORMAL} : ${WHITE}${CTESTS_PERFORMED}${NORMAL}\"\n            if [ ${SKIP_PLUGINS} -eq 0 ]; then\n                echo \"  ${CYAN}Plugins enabled${NORMAL} : ${WHITE}${N_PLUGIN_ENABLED}${NORMAL}\"\n            else\n                echo \"  ${CYAN}Plugins enabled${NORMAL} : ${WHITE}Skipped${NORMAL}\"\n            fi\n            echo \"\"\n            echo \"  ${SECTION}Software components${NORMAL}:\"\n            if [ ${FIREWALL_ACTIVE} -eq 1 ]; then FIREWALL=\"${GREEN}V\"; else FIREWALL=\"${RED}X\"; fi\n            if [ ${MALWARE_SCANNER_INSTALLED} -eq 1 ]; then MALWARE=\"${GREEN}V\"; else MALWARE=\"${RED}X\"; fi\n            if [ ${IDS_IPS_TOOL_FOUND} -eq 1 ]; then IDSIPS=\"${GREEN}V\"; else IDSIPS=\"${RED}X\"; fi\n\n            echo \"  - Firewall               [${FIREWALL}${NORMAL}]\"\n            #echo \"  - Integrity monitoring   [${IDSIPS}${NORMAL}]\"\n            echo \"  - Intrusion software     [${IDSIPS}${NORMAL}]\"\n            echo \"  - Malware scanner        [${MALWARE}${NORMAL}]\"\n\n            echo \"\"\n            echo \"  ${SECTION}Files${NORMAL}:\"\n            echo \"  - Test and debug information      : ${WHITE}${LOGFILE}${NORMAL}\"\n            echo \"  - Report data                     : ${WHITE}${REPORTFILE}${NORMAL}\"\n            echo \"\"\n            echo \"================================================================================\"\n            if [ ${PROGRAM_LV} -gt ${PROGRAM_AC} ]; then\n                echo \"  ${NOTICE}Notice: ${WHITE}${PROGRAM_NAME} ${GEN_UPDATE_AVAILABLE}${NORMAL}\"\n                echo \"  ${GEN_CURRENT_VERSION} : ${WHITE}${PROGRAM_AC}${NORMAL}    ${GEN_LATEST_VERSION} : ${WHITE}${PROGRAM_LV}${NORMAL}\"\n                echo \"================================================================================\"\n            else\n                if [ ${OLD_RELEASE} -eq 1 ]; then\n                    echo \"\"\n                    echo \"  ${NOTICE}Notice: ${WHITE}This version of ${PROGRAM_NAME} is older than 6 months and might be outdated. Check the project page if a newer version is available.${NORMAL}\"\n                    echo \"\"\n                echo \"================================================================================\"\n                fi \n                ###########################################################################################\n                #\n                # Software quality program\n                # Only provide this hint when the tool is at the latest version\n                #\n                ###########################################################################################\n\n                if [ ! \"${PROGRAM_LV}\" = \"0\" -a ! \"${REPORTFILE}\" = \"\" -a ! \"${REPORTFILE}\" = \"/dev/null\" ]; then\n\n                    # Determine if the quality of the program can be increased by filtering out the exceptions\n                    FIND=$(${GREPBINARY} \"^exception\" ${REPORTFILE})\n                    if [ -n \"${FIND}\" ]; then\n                        echo \"\"\n                        echo \"  ${RED}${NOTE_EXCEPTIONS_FOUND}${NORMAL}\"\n                        echo \"  ${WHITE}${NOTE_EXCEPTIONS_FOUND_DETAILED}!${NORMAL}\"\n                        echo \"\"\n                        echo \"  ${CYAN}${GEN_WHAT_TO_DO}:${NORMAL}\"\n                        echo \"  ${TEXT_YOU_CAN_HELP_LOGFILE} (${LOGFILE}).\"\n                        echo \"  Go to https://cisofy.com/contact/ and send your file to the e-mail address listed\"\n                        echo \"\"\n                        echo \"================================================================================\"\n                    fi\n                fi\n\n                # If end-of-life check failed, ask to submit\n                if [ ! \"${PROGRAM_LV}\" = \"0\" -a ${EOL} -eq 255 ]; then\n                    echo \"\"\n                    echo \"  ${SECTION}Notice: ${WHITE}No OS entry was found in the end-of-life database${NORMAL}\"\n                    echo \"\"\n                    echo \"  ${CYAN}${GEN_WHAT_TO_DO}:${NORMAL}\"\n                    echo \"  Please submit a pull request on GitHub to include your OS version and the end date of this OS version is being supported\"\n                    echo \"  URL: ${PROGRAM_SOURCE}\"\n                    echo \"\"\n                    echo \"================================================================================\"\n                fi \n            fi\n\n            # Display what tests are skipped in non-privileged scan for awareness\n            if [ ${PENTESTINGMODE} -eq 1 -a ! \"${SKIPPED_TESTS_ROOTONLY}\" = \"\" ]; then\n                echo \"\"\n                echo \"  ${PURPLE}${NOTE_SKIPPED_TESTS_NON_PRIVILEGED}:${NORMAL}\"\n                echo \"\"\n                FIND=$(echo ${SKIPPED_TESTS_ROOTONLY} | sed 's/ /:space:/g')\n                # Split entries\n                FIND=$(echo ${FIND} | sed 's/====/ /g')\n                # Display found entries\n                for ITEM in ${FIND}; do\n                    OUTPUT=$(echo ${ITEM} | sed 's/:space:/ /g')\n                    echo \"    ${OUTPUT}\"\n                done\n                echo \"\"\n                echo \"================================================================================\"\n            fi\n\n            echo \"\"\n        fi\n\n    fi\n\n    # Report data, even if it is not displayed on screen\n    Report \"hardening_index=${HPINDEX}\"\n\n    if [ ${QUIET} -eq 0 ]; then\n        echo \"  ${WHITE}${PROGRAM_NAME}${NORMAL} ${PROGRAM_VERSION}\"\n        echo \"\"\n        echo \"  Auditing, system hardening, and compliance for UNIX-based systems\"\n        echo \"  (Linux, macOS, BSD, and others)\"\n        echo \"\"\n        echo \"  ${PROGRAM_COPYRIGHT}\"\n        echo \"  ${WHITE}${PROGRAM_EXTRAINFO}${NORMAL}\"\n        echo \"\"\n        echo \"================================================================================\"\n    fi\n\n# EOF\n"
  },
  {
    "path": "include/tests_accounting",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_ACCOUNTING}\"\n#\n#################################################################################\n#\n    AUDITD_CONF_LOCS=\"${ROOTDIR}etc ${ROOTDIR}etc/audit\"\n    AUDITD_CONF_FILE=\"\"\n    CMD_CONF_LOCS=\"${ROOTDIR}etc ${ROOTDIR}etc/cmd\"\n    CMD_CONF_FILE=\"\"\n    LINUX_AUDITD_RUNNING=0\n    LINUX_CMD_RUNNING=0\n    AUDIT_DAEMON_RUNNING=0\n    SOLARIS_AUDITD_RUNNING=0\n#\n#################################################################################\n#\n    # Test        : ACCT-2754\n    # Description : Check availability FreeBSD accounting data\n    Register --test-no ACCT-2754 --os FreeBSD --weight L --network NO --category security --description \"Check for available FreeBSD accounting information\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}var/account/acct ]; then\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: ${ROOTDIR}var/account/acct available\"\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            LogText \"Result: No accounting information available\"\n            LogText \"Remark: Possibly there is another location where the accounting data is stored\"\n            ReportSuggestion \"${TEST_NO}\" \"Enable process accounting\"\n            AddHP 2 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-2760\n    # Description : Check availability OpenBSD accounting data\n    Register --test-no ACCT-2760 --os OpenBSD --weight L --network NO --category security --description \"Check for available OpenBSD accounting information\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}var/account/acct ]; then\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: ${ROOTDIR}var/account/acct available\"\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            LogText \"Result: No accounting information available\"\n            LogText \"Remark: Possibly there is another location where the accounting data is stored\"\n            ReportSuggestion \"${TEST_NO}\" \"Enable process accounting\"\n            AddHP 2 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9622\n    # Description : Check availability Linux accounting data\n    # Notes       : /var/log/pacct (Slackware)\n    Register --test-no ACCT-9622 --os Linux --weight L --network NO --category security --description \"Check for available Linux accounting information\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check accounting information\"\n        if [ -f ${ROOTDIR}var/account/pacct ]; then\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: ${ROOTDIR}var/account/pacct available\"\n            AddHP 3 3\n        elif [ -f ${ROOTDIR}var/log/account/pacct ]; then\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: ${ROOTDIR}var/log/account/pacct available\"\n            AddHP 3 3\n        elif [ -f ${ROOTDIR}var/log/pacct ]; then\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: ${ROOTDIR}var/log/pacct available\"\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- Checking accounting information\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            LogText \"Result: No accounting information available (${ROOTDIR}var/account/pacct, ${ROOTDIR}var/log/account/pacct nor ${ROOTDIR}var/log/pacct exist)\"\n            LogText \"Remark: Possibly there is another location where the accounting data is stored\"\n            ReportSuggestion \"${TEST_NO}\" \"Enable process accounting\"\n            AddHP 2 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9626\n    # Description : Check sysstat accounting data\n    Register --test-no ACCT-9626 --os Linux --weight L --network NO --category security --description \"Check for sysstat accounting data\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check ${ROOTDIR}etc/default/sysstat presence\"\n        if [ -f ${ROOTDIR}etc/default/sysstat ]; then\n            LogText \"Result: ${ROOTDIR}etc/default/sysstat found\"\n            FIND=$(${GREPBINARY} \"^ENABLED\" ${ROOTDIR}etc/default/sysstat | ${GREPBINARY} -i true)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: sysstat enabled via ${ROOTDIR}etc/default/sysstat\"\n                Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                LogText \"Result: sysstat disabled via ${ROOTDIR}etc/default/sysstat\"\n                Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_DISABLED}\" --color WHITE\n                ReportSuggestion \"${TEST_NO}\" \"Enable sysstat to collect accounting (disabled)\"\n            fi\n        elif [ -f ${ROOTDIR}etc/cron.d/sysstat ]; then\n            FIND=$(${GREPBINARY} -v '^[[:space:]]*\\(#\\|$\\)' ${ROOTDIR}etc/cron.d/sysstat)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: sysstat enabled via ${ROOTDIR}etc/cron.d/sysstat\"\n                Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                LogText \"Result: sysstat disabled via ${ROOTDIR}etc/cron.d/sysstat\"\n                Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_DISABLED}\" --color WHITE\n                ReportSuggestion \"${TEST_NO}\" \"Enable sysstat to collect accounting (cron disabled)\"\n            fi\n        elif [ -f \"${ROOTDIR}lib/systemd/system/sysstat.service\" ] || [ -f \"${ROOTDIR}etc/systemd/system/sysstat.service\" ]; then\n            LogText \"Result: sysstat systemd unit found\"\n            if [ -L \"${ROOTDIR}etc/systemd/system/multi-user.target.wants/sysstat.service\" ]; then\n                # Assuming -collect.timer and -summary.timer are enabled as well,\n                # as they are usually in the install section.\n                LogText \"Result: sysstat enabled via systemd\"\n                Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                LogText \"Result: sysstat disabled via systemd\"\n                Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_DISABLED}\" --color WHITE\n            fi\n        else\n            LogText \"Result: sysstat not found via ${ROOTDIR}etc/default/sysstat or ${ROOTDIR}etc/cron.d/sysstat or as a systemd unit\"\n            Display --indent 2 --text \"- Checking sysstat accounting data\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Enable sysstat to collect accounting (no results)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9628\n    # Description : Check auditd status\n    if [ -n \"${AUDITDBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9628 --os Linux --weight L --network NO --category security --description \"Check for auditd\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check auditd status\"\n        # Should not get kauditd\n        if IsRunning \"auditd\"; then\n            LogText \"Result: auditd running\"\n            Display --indent 2 --text \"- Checking auditd\" --result \"${STATUS_ENABLED}\" --color GREEN\n            LINUX_AUDITD_RUNNING=1\n            AUDIT_DAEMON_RUNNING=1\n            Report \"audit_trail_tool[]=auditd\"\n            Report \"linux_auditd_running=1\"\n            AddHP 4 4\n        else\n            LogText \"Result: auditd not active\"\n            Display --indent 2 --text \"- Checking auditd\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            if [ ! \"${VMTYPE}\" = \"openvz\" ]; then\n                ReportSuggestion \"${TEST_NO}\" \"Enable auditd to collect audit information\"\n            fi\n            AddHP 0 1\n            Report \"linux_auditd_running=0\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9630\n    # Description : Check auditd rules\n    if [ -n \"${AUDITDBINARY}\" -a -n \"${AUDITCTLBINARY}\" -a ${LINUX_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9630 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description \"Check for auditd rules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking auditd rules\"\n        FIND=$(${AUDITCTLBINARY} -l | ${GREPBINARY} -v \"No rules\")\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: auditd rules empty\"\n            Display --indent 4 --text \"- Checking audit rules\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            AddHP 0 2\n            ReportSuggestion \"${TEST_NO}\" \"Audit daemon is enabled with an empty ruleset. Disable the daemon or define rules\"\n        else\n            LogText \"Result: found auditd rules\"\n            Display --indent 4 --text \"- Checking audit rules\" --result \"${STATUS_OK}\" --color GREEN\n            # Log audit daemon rules\n            FIND=$(${AUDITCTLBINARY} -l | ${SEDBINARY} 's/ /!space!/g')\n            for RULE in ${FIND}; do\n                RULE=$(echo ${RULE} | ${SEDBINARY} 's/!space!/ /g')\n                LogText \"Output: ${RULE}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9632\n    # Description : Check auditd configuration file\n    if [ -n \"${AUDITDBINARY}\" -a ${LINUX_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9632 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for auditd configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking auditd configuration file\"\n        for DIR in ${AUDITD_CONF_LOCS}; do\n            if [ -f ${DIR}/auditd.conf ]; then\n                AUDITD_CONF_FILE=\"${DIR}/auditd.conf\"\n                LogText \"Result: Found ${DIR}/auditd.conf\"\n            else\n                LogText \"Result: ${DIR}/auditd.conf not found\"\n            fi\n        done\n        # Check if we discovered the configuration file. It should be there is the binaries are available and process is running\n        if [ -n \"${AUDITD_CONF_FILE}\" ]; then\n            Display --indent 4 --text \"- Checking audit configuration file\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: could not find auditd configuration file\"\n            Display --indent 4 --text \"- Checking audit configuration file\" --result \"${STATUS_FOUND}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Determine the location of auditd configuration file\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9634\n    # Description : Check auditd log file\n    if [ -n \"${AUDITDBINARY}\" -a ${LINUX_AUDITD_RUNNING} -eq 1 -a -n \"${AUDITD_CONF_FILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9634 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for auditd log file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking auditd log file\"\n        DEFAULT_LOCATION=\"/var/log/audit/audit.log\"\n        FIND=$(${GREPBINARY} \"^log_file\" ${AUDITD_CONF_FILE} | ${AWKBINARY} '{ if ($1==\"log_file\" && $2==\"=\") { print $3 } }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: log file is defined\"\n            LogText \"Defined value: ${FIND}\"\n        else\n            LogText \"Result: log file is not defined\"\n            LogText \"Assumed default location: ${DEFAULT_LOCATION}\"\n            FIND=\"${DEFAULT_LOCATION}\"\n        fi\n\n        if [ -f ${FIND} ]; then\n            LogText \"Result: log file ${FIND} exists on disk\"\n            Display --indent 4 --text \"- Checking auditd log file\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"logfile[]=${FIND}\"\n        else\n            LogText \"Result: can't find log file ${FIND} on disk\"\n            Display --indent 4 --text \"- Checking auditd log file\" --result \"${STATUS_SUGGESTION}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Check auditd log file location\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9636\n    # Description : Check for Snoopy (wrapper for execve() and logger)\n    Register --test-no ACCT-9636 --os Linux --weight L --network NO --category security --description \"Check for Snoopy wrapper and logger\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FILE=\"${ROOTDIR}lib/snoopy.so\"\n        if [ -f ${FILE} ]; then\n            LogText \"Result: found ${FILE}\"\n            Display --indent 2 --text \"- Checking Snoopy\" --result \"${STATUS_FOUND}\" --color GREEN\n            if [ -f ${ROOTDIR}etc/ld.so.preload ]; then\n                LogText \"Result: found ${ROOTDIR}etc/ld.so.preload, testing if snoopy.so is listed\"\n                FIND=$(${GREPBINARY} ${FILE} ${ROOTDIR}etc/ld.so.preload)\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found snoopy in ld.so.preload\"\n                    LogText \"Output: ${FIND}\"\n                    Display --indent 6 --text \"- Library in ld.so.preload\" --result \"LOADED\" --color GREEN\n                    Report \"audit_trail_tool[]=snoopy\"\n                else\n                    Display --indent 6 --text \"- Library in ld.so.preload\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Snoopy is installed but not loaded via ${ROOTDIR}etc/ld.so.preload\"\n                    AddHP 3 3\n                fi\n            else\n                LogText \"Result: ${ROOTDIR}etc/ld.so.preload does not exist\"\n                Display --indent 6 --text \"- Library in ld.so.preload\" --result \"${STATUS_UNKNOWN}\" --color PURPLE\n                ReportException \"${TEST_NO}:1\" \"Unsure how Snoopy might be loaded as ld.so.preload does not exist\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9650\n    # Description : Check Solaris audit daemon presence\n    Register --test-no ACCT-9650 --os Solaris --weight L --network NO --category security --description \"Check Solaris audit daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check if audit daemon is running\"\n        if IsRunning \"auditd\"; then\n            LogText \"Result: Solaris audit daemon is running\"\n            SOLARIS_AUDITD_RUNNING=1\n            AUDIT_DAEMON_RUNNING=1\n            Display --indent 2 --text \"- Checking Solaris audit daemon status\" --result \"${STATUS_RUNNING}\" --color GREEN\n        else\n            LogText \"Result: Solaris audit daemon is not running\"\n            Display --indent 2 --text \"- Checking Solaris audit daemon status\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9652\n    # Description : Check Solaris auditd service status\n    if [ -x ${ROOTDIR}usr/bin/svcs -a ${SOLARIS_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9652 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check auditd SMF status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check if auditd service is enabled and online\"\n        FIND=$(${ROOTDIR}usr/bin/svcs svc:/system/auditd:default | ${GREPBINARY} \"^online\")\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: auditd service is online\"\n            Display --indent 4 --text \"- Checking Solaris audit daemon status\" --result \"${STATUS_ON}\"LINE --color GREEN\n        else\n            Display --indent 4 --text \"- Checking Solaris audit daemon status\" --result \"NOT ONLINE\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Check status of audit daemon\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9654\n    # Description : Check Solaris Basic Security Mode (BSM) in /etc/system\n    if [ ${SOLARIS_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9654 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check BSM auditing in ${ROOTDIR}etc/system\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check if BSM is enabled in ${ROOTDIR}etc/system\"\n        if [ -f ${ROOTDIR}etc/system ]; then\n            FIND=$(${GREPBINARY} 'set c2audit:audit_load = 1' ${ROOTDIR}etc/system)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: BSM is enabled in ${ROOTDIR}etc/system\"\n                Display --indent 4 --text \"- Checking Solaris BSM (${ROOTDIR}etc/system)\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                Display --indent 4 --text \"- Checking Solaris BSM (${ROOTDIR}etc/system)\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            fi\n        else\n            LogText \"Result: ${ROOTDIR}etc/system does not exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9656\n    # Description : Check Solaris BSM (c2audit) module status\n    # Notes       : todo - replace direct binary call\n    if [ ${SOLARIS_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9656 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check BSM auditing in module list\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check if c2audit module is active\"\n        if [ -x ${ROOTDIR}usr/sbin/modinfo ]; then\n            FIND=$(${ROOTDIR}usr/sbin/modinfo | ${GREPBINARY} c2audit)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: c2audit found in modinfo output\"\n                Display --indent 4 --text \"- Checking Solaris BSM (modules list)\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                LogText \"Result: c2audit not found in modinfo output\"\n                Display --indent 4 --text \"- Checking Solaris BSM (modules list)\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            fi\n        else\n            LogText \"Result: ${ROOTDIR}usr/sbin/modinfo does not exist, skipping test\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9660\n    # Description : Check location for audit events\n    if [ ${SOLARIS_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9660 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check location of audit events\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check ${ROOTDIR}etc/security/audit_control for event logging location\"\n        if [ -f ${ROOTDIR}etc/security/audit_control ]; then\n            LogText \"Result: file ${ROOTDIR}etc/security/audit_control found\"\n            FIND=$(${GREPBINARY} \"^dir\" ${ROOTDIR}etc/security/audit_control | ${AWKBINARY} -F: '{ print $2 }')\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found location ${FIND}\"\n                LogText \"Test: Checking if location is a valid directory\"\n                if [ -d ${FIND} ]; then\n                    LogText \"Result: location ${FIND} is valid\"\n                    Display --indent 4 --text \"- Checking Solaris audit location\" --result \"${STATUS_FOUND}\" --color GREEN\n                else\n                    LogText \"Result: location ${FIND} does not exist\"\n                    Display --indent 4 --text \"- Checking Solaris audit location\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Check if the Solaris audit directory is available\"\n                fi\n            else\n                LogText \"Result: unknown event location\"\n                Display --indent 4 --text \"- Checking Solaris audit location\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Check if the Solaris audit directory is properly configured\"\n            fi\n        else\n            LogText \"Result: could not find ${ROOTDIR}etc/security/audit_control\"\n            Display --indent 4 --text \"- Checking Solaris audit location\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9662\n    # Description : check auditstat\n    if [ ${SOLARIS_AUDITD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9662 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Solaris auditing stats\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check auditing statistics\"\n        if [ -x ${ROOTDIR}usr/sbin/auditstat ]; then\n            FIND=$(${ROOTDIR}usr/sbin/auditstat | ${TRBINARY} -s ' ' ',')\n            for ITEM in ${FIND}; do\n                LogText \"Output: ${ITEM}\"\n            done\n            Display --indent 4 --text \"- Checking Solaris audit statistics\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            LogText \"Result: ${ROOTDIR}usr/sbin/auditstat not found, skipping test\"\n            Display --indent 4 --text \"- Checking Solaris audit statistics\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9670\n    # Description : Check cmd status\n    if [ -n \"${CMDBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9670 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for cmd\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check cmd status\"\n        if IsRunning \"cmd_daemon\"; then\n            LogText \"Result: cmd running\"\n            Display --indent 2 --text \"- Checking cmd\" --result \"${STATUS_ENABLED}\" --color GREEN\n            LINUX_CMD_RUNNING=1\n            AUDIT_DAEMON_RUNNING=1\n            Report \"audit_trail_tool[]=cmd\"\n            Report \"linux_cmd_running=1\"\n            AddHP 4 4\n        else\n            LogText \"Result: cmd not active\"\n            Display --indent 2 --text \"- Checking cmd\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            if [ ! \"${VMTYPE}\" = \"openvz\" ]; then\n                ReportSuggestion \"${TEST_NO}\" \"Install cmd to collect audit information\"\n            fi\n            AddHP 0 1\n            Report \"linux_cmd_running=0\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : ACCT-9672\n    # Description : Check cmd configuration file\n    if [ -n \"${CMDBINARY}\" -a ${LINUX_CMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no ACCT-9672 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for cmd configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking cmd configuration file\"\n        for DIR in ${CMD_CONF_LOCS}; do\n            if [ -f ${DIR}/config.ini ]; then\n                CMD_CONF_FILE=\"${DIR}/config.ini\"\n                LogText \"Result: Found ${DIR}/config.ini\"\n            else\n                LogText \"Result: ${DIR}/config.ini not found\"\n            fi\n        done\n        # Check if we discovered the configuration file. It should be there is the binaries are available and process is running\n        if [ -n \"${CMD_CONF_FILE}\" ]; then\n            Display --indent 4 --text \"- Checking cmd configuration file\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: could not find cmd configuration file\"\n            Display --indent 4 --text \"- Checking cmd configuration file\" --result \"${STATUS_FOUND}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Determine the location of cmd configuration file\"\n        fi\n    fi\n#\n#################################################################################\n#\n    Report \"audit_daemon_running=${AUDIT_DAEMON_RUNNING}\"\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_authentication",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# User, Group and authentication tests\n#\n#################################################################################\n#\n    LDAP_AUTH_ENABLED=0\n    LDAP_PAM_ENABLED=0\n    LDAP_CONF_LOCATIONS=\"${ROOTDIR}etc/ldap.conf ${ROOTDIR}etc/ldap/ldap.conf ${ROOTDIR}etc/openldap/ldap.conf ${ROOTDIR}usr/local/etc/ldap.conf ${ROOTDIR}usr/local/etc/openldap/ldap.conf\"\n    PAM_FILE_LOCATIONS=\"${ROOTDIR}usr/lib/aarch64-linux-gnu/security ${ROOTDIR}lib/arm-linux-gnueabihf/security ${ROOTDIR}lib/i386-linux-gnu/security ${ROOTDIR}lib/security ${ROOTDIR}lib/x86_64-linux-gnu/security ${ROOTDIR}lib/powerpc64le-linux-gnu/security ${ROOTDIR}lib64/security ${ROOTDIR}usr/lib /usr/lib/security\"\n    SUDOERS_LOCATIONS=\"${ROOTDIR}etc/sudoers ${ROOTDIR}usr/local/etc/sudoers ${ROOTDIR}usr/pkg/etc/sudoers\"\n    SUDOERS_FILE=\"\"\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_USERS_GROUPS_AND_AUTHENTICATION}\"\n\n    # Test        : AUTH-9204\n    # Description : Check users with UID zero (0)\n    # Notes       : Ignores :0: in file if match is in NIS related line\n    Register --test-no AUTH-9204 --weight L --network NO --category security --description \"Check users with an UID of zero\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Search accounts with UID 0\n        LogText \"Test: Searching accounts with UID 0\"\n        # Check if device is a QNAP, as the root user is called admin, and not root\n        if [ ${QNAP_DEVICE} -eq 1 ]; then\n            FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${GREPBINARY} -E -v '^#|^admin:|^(\\+:\\*)?:0:0:::' | ${CUTBINARY} -d \":\" -f1,3 | ${GREPBINARY} ':0')\n        else\n            FIND=$(${GREPBINARY} ':0:' ${ROOTDIR}etc/passwd | ${GREPBINARY} -E -v '^#|^root:|^(\\+:\\*)?:0:0:::' | ${CUTBINARY} -d \":\" -f1,3 | ${GREPBINARY} ':0')\n        fi\n        if [ -n \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Administrator accounts\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Found more than one administrator accounts\"\n            ReportWarning \"${TEST_NO}\" \"Multiple users with UID 0 found in passwd file\"\n            for USER in ${FIND}; do\n                LogText \"Administrator account: ${USER}\"\n                Report \"user_with_uid_zero[]=${USER}\"\n                if [ \"${USER}\" = \"toor\" ]; then\n                    LogText \"BSD note: default there is a user 'toor' installed. This account is considered useless unless it\"\n                    LogText \"is assigned a password and used for daily operations or emergencies. ie: bad shell for root user.\"\n                    ReportSuggestion \"${TEST_NO}\" \"Use vipw to delete the 'toor' user if not used.\"\n                fi\n            done\n        else\n            Display --indent 2 --text \"- Administrator accounts\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: No accounts found with UID 0 other than root.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9208\n    # Description : Check non-unique accounts\n    Register --test-no AUTH-9208 --weight L --network NO --category security --description \"Check non-unique accounts in passwd file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for non-unique accounts\"\n        if  [ \"${OS}\" = \"DragonFly\" -o \"${OS}\" = \"FreeBSD\" -o \"${OS}\" = \"NetBSD\" -o \"${OS}\" = \"OpenBSD\" ]; then\n            PASSWD_FILE=\"${ROOTDIR}etc/master.passwd\"\n          else\n            PASSWD_FILE=\"${ROOTDIR}etc/passwd\"\n        fi\n        # Check password file\n        if [ -f ${PASSWD_FILE} ]; then\n            FIND=$(${GREPBINARY} -v '^#' ${PASSWD_FILE} | ${CUTBINARY} -d ':' -f3 | ${SORTBINARY} | uniq -d)\n            if [ \"${FIND}\" = \"\" ]; then\n                Display --indent 2 --text \"- Unique UIDs\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: all accounts found in ${PASSWD_FILE} are unique\"\n            else\n                Display --indent 2 --text \"- Unique UIDs\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: found multiple accounts with same UID\"\n                LogText \"Output (non-unique UIDs): ${FIND}\"\n                ReportWarning \"${TEST_NO}\" \"Multiple accounts found with same UID\"\n            fi\n          else\n            Display --indent 2 --text \"- Unique UIDs\" --result \"${STATUS_SKIPPED}\" --color WHITE\n            LogText \"Result: test skipped, ${PASSWD_FILE} file not available\"\n        fi\n        LogText \"Remarks: Non unique UIDs can be a risk for the system or part of a configuration mistake\"\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9212\n    # Description : Test group file with chkgrp tool (ie FreeBSD)\n    LogText \"Prerequisite test: /usr/sbin/chkgrp\"\n    if [ -x ${ROOTDIR}usr/sbin/chkgrp ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9212 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Test group file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking chkgrp tool\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: /usr/sbin/chkgrp binary found. Using this to perform next test(s).\"\n        LogText \"Test: Testing consistency of /etc/group file\"\n        FIND=$(${ROOTDIR}usr/sbin/chkgrp | ${GREPBINARY} -v 'is fine')\n        if [ \"${FIND}\" = \"\" ]; then\n            Display --indent 4 --text \"- Checking consistency of /etc/group file\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: chkgrp test performed, Group file seems to be ok.\"\n          else\n            Display --indent 4 --text \"- Checking consistency of /etc/group file\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: chkgrp found some errors. Run the tool manually to see details.\"\n            LogText \"chkgrp output: ${FIND}\"\n            ReportWarning \"${TEST_NO}\" \"chkgrp reported inconsistencies in /etc/group file\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9216\n    # Description : Check /etc/group and shadow group files\n    # Notes       : Run grpck to test group files (most likely /etc/group and shadow group files)\n    if [ -n \"${GRPCKBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9216 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description \"Check group and shadow group files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for grpck binary output\"\n\n        case ${OS} in\n            \"AIX\")  FIND=$(${GRPCKBINARY} -n ALL 2> /dev/null ; echo $?) ;;\n            \"Linux\")\n                if [ \"${LINUX_VERSION}\" = \"SuSE\" ]; then\n                    FIND=$(${GRPCKBINARY} -q -r > /dev/null ; echo $?)\n                else\n                    FIND=$(${GRPCKBINARY} -r 2> /dev/null ; echo $?)\n                fi\n                ;;\n            *)      FIND=$(${GRPCKBINARY} 2> /dev/null ; echo $?) ;;\n        esac\n\n        # Check exit-code\n        if [ \"${FIND}\" = \"0\" ]; then\n            Display --indent 2 --text \"- Consistency of group files (grpck)\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: grpck binary didn't find any errors in the group files\"\n        else\n            Display --indent 2 --text \"- Consistency of group files (grpck)\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"grpck binary found errors in one or more group files\"\n        fi\n        unset FIND\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9218\n    # Description : Check login shells for passwordless accounts\n    # Notes       : Results should be checked\n    Register --test-no AUTH-9218 --os \"DragonFly FreeBSD NetBSD OpenBSD\" --root-only YES --weight L --network NO --category security --description \"Check login shells for passwordless accounts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: Checking login shells\"\n        if [ -f ${ROOTDIR}etc/master.passwd ]; then\n            # Check for all shells, except: (/usr)/sbin/nologin /nonexistent\n            FIND=$(${GREPBINARY} \"[a-z]:\\*:\" ${ROOTDIR}etc/master.passwd | ${GREPBINARY} -E -v '^#|/sbin/nologin|/usr/sbin/nologin|/nonexistent' | ${SEDBINARY} 's/ /!space!/g')\n            if [ -z \"${FIND}\" ]; then\n                Display --indent 2 --text \"- Login shells\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                Display --indent 2 --text \"- Login shells\" --result \"${STATUS_WARNING}\" --color RED\n                for LINE in ${FIND}; do\n                    LINE=$(echo ${LINE} | ${SEDBINARY} 's/!space!/ /g')\n                    SHELL=$(echo ${LINE} | ${AWKBINARY} -F: '{ print $10 }')\n                    LogText \"Output: ${LINE}\"\n                    if [ -z \"${SHELL}\" ]; then\n                        LogText \"Result: found no shell on line\"\n                    else\n                        LogText \"Result: found possible harmful shell ${SHELL}\"\n                        if [ -f ${SHELL} ]; then\n                            LogText \"Result: shell ${SHELL} does exist\"\n                            FOUND=1\n                        else\n                            LogText \"Result: shell ${SHELL} does not exist\"\n                            ReportSuggestion \"${TEST_NO}\" \"Determine if account is needed, as shell ${SHELL} does not exist\"\n                        fi\n                    fi\n                done\n                if [ ${FOUND} -eq 1 ]; then\n                    ReportWarning \"${TEST_NO}\" \"Possible harmful shell found (for passwordless account!)\"\n                fi\n            fi\n          else\n            Display --indent 2 --text \"- Login shells\" --result \"${STATUS_SKIPPED}\" --color WHITE\n            LogText \"Result: No ${ROOTDIR}etc/master.passwd file found\"\n        fi\n        unset LINE SHELL\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9222\n    # Description : Check unique group IDs\n    Register --test-no AUTH-9222 --weight L --network NO --category security --description \"Check unique groups (IDs)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for non unique group ID's in /etc/group\"\n        FIND=$(${GREPBINARY} -v '^#' ${ROOTDIR}etc/group | ${GREPBINARY} -v '^$' | ${AWKBINARY} -F: '{ print $3 }' | ${SORTBINARY} | uniq -d)\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Unique group IDs\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: All group ID's are unique\"\n            Report \"auth_group_ids_unique=1\"\n        else\n            Display --indent 2 --text \"- Unique group IDs\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Found the same group ID multiple times\"\n            for I in ${FIND}; do\n                Report \"auth_groups_nonunique[]=${I}\"\n                LogText \"Non-unique group: ${I}\"\n            done\n            ReportSuggestion \"${TEST_NO}\" \"Check your /etc/group file and correct any inconsistencies\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9226\n    # Description : Check unique group names\n    if [ -f ${ROOTDIR}etc/group ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9226 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check unique group names\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for non unique group names in ${ROOTDIR}etc/group\"\n        FIND=$(${GREPBINARY} -v '^#' ${ROOTDIR}etc/group | ${GREPBINARY} -v '^$' | ${AWKBINARY} -F: '{ print $1 }' | ${SORTBINARY} | uniq -d)\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Unique group names\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: All group names are unique\"\n            Report \"auth_group_names_unique=1\"\n        else\n            Display --indent 2 --text \"- Unique group names\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Found the same group name multiple times\"\n            for I in ${FIND}; do\n                Report \"auth_groups_nonunique[]=${I}\"\n                LogText \"Non-unique group: ${I}\"\n            done\n            ReportSuggestion \"${TEST_NO}\" \"Check your ${ROOTDIR}etc/group file and correct any inconsistencies\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9228\n    # Description : Check password file consistency with pwck\n    # Notes       : Operating systems include Linux, Solaris\n    if [ -x ${ROOTDIR}usr/sbin/pwck ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9228 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check password file consistency with pwck\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking password file consistency (pwck)\"\n        TESTED=0\n        case ${OS} in\n            \"Linux\")\n                FIND=$(${ROOTDIR}usr/sbin/pwck -q -r 2> /dev/null; echo $?)\n                TESTED=1\n            ;;\n            \"Solaris\" | \"HP-UX\")\n                FIND=$(${ROOTDIR}usr/sbin/pwck 2> /dev/null; echo $?)\n                TESTED=1\n            ;;\n            *)\n                LogText \"Dev: found ${ROOTDIR}usr/sbin/pwck, but unsure how to call it on this operating system\"\n                ReportException \"${TEST_NO}:1\" \"Found ${ROOTDIR}usr/sbin/pwck, but unsure how to call it on this operating system\"\n            ;;\n        esac\n        # Only display if this test has been executed\n        if [ ${TESTED} -eq 1 -a \"${FIND}\" = \"0\" ]; then\n            Display --indent 2 --text \"- Password file consistency\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: pwck check didn't find any problems\"\n            AddHP 2 2\n        else\n            Display --indent 2 --text \"- Password file consistency\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: pwck found one or more errors/warnings in the password file.\"\n            ReportSuggestion \"${TEST_NO}\" \"Run pwck manually and correct any errors in the password file\"\n            AddHP 0 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9229\n    # Description : Check password hashing methods vs. recommendations in crypt(5)\n    # Notes       : Applicable to all Unix-like OS\n    #               Requires read access to /etc/shadow (if it exists)\n\n    ParsePasswordEntry() {\n        METHOD=$1\n        case ${METHOD} in\n            1:\\* | 1:x | 0: | *:!* | *LOCK*)\n                # disabled | shadowed | no password | locked account (can be literal *LOCK* or something like LOCKED)\n                ;;\n            *:\\$5\\$*| *:\\$6\\$*)\n                # sha256crypt | sha512crypt: check number of rounds, should be >=5000\n                ROUNDS=$(echo \"${METHOD}\" | sed -n 's/.*rounds=\\([0-9]*\\)\\$.*/\\1/gp')\n                if [ -z \"${ROUNDS}\" ]; then\n                    echo 'sha256crypt/sha512crypt(default=5000rounds)'\n                elif [ \"${ROUNDS}\" -lt 5000 ]; then\n                    echo 'sha256crypt/sha512crypt(<5000rounds)'\n                fi\n                ;;\n            *:\\$y\\$* | *:\\$gy\\$* | *:\\$2b\\$* | *:\\$7\\$*)\n                # yescrypt | gost-yescrypt | bcrypt | scrypt\n                ;;\n            *:_*)\n                echo bsdicrypt\n                ;;\n            *:\\$1\\$*)\n                echo md5crypt\n                ;;\n            *:\\$3\\$*)\n                echo NT\n                ;;\n            *:\\$md5*)\n                echo SunMD5\n                ;;\n            *:\\$sha1*)\n                echo sha1crypt\n                ;;\n            13:* | 178:*)\n                echo bigcrypt/descrypt\n                ;;\n            *)\n                echo \"Unknown password hashing method ${METHOD}. Please report to lynis-dev@cisofy.com\"\n                ;;\n        esac\n    }\n\n    Register --test-no AUTH-9229 --root-only YES --weight L --network NO --category security --description \"Check password hashing methods\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking password hashing methods\"\n        SHADOW=\"\";\n        if [ -e ${ROOTDIR}etc/shadow ]; then SHADOW=\"${ROOTDIR}etc/shadow\"; fi\n        FIND=$(${CAT_BINARY} ${ROOTDIR}etc/passwd ${SHADOW} | ${AWKBINARY} -F : '{print length($2) \":\" $2 }' | while read METHOD; do\n            ParsePasswordEntry ${METHOD}\n        done | ${SORTBINARY} -u | ${TRBINARY} '\\n' ' ')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Password hashing methods\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: no poor password hashing methods found\"\n            AddHP 2 2\n        else\n            Display --indent 2 --text \"- Password hashing methods\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: poor password hashing methods found: ${FIND}\"\n            ReportSuggestion \"${TEST_NO}\" \"Check PAM configuration, add rounds if applicable and expire passwords to encrypt with new values\"\n            AddHP 0 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9230\n    # Description : Check password hashing rounds in login.defs\n    # Notes       : Applicable to all Unix-like OS\n    PREQS_MET=\"NO\"\n    if [ -f ${ROOTDIR}etc/login.defs ]; then\n        PREQS_MET=\"YES\"\n    fi\n    Register --test-no AUTH-9230 --preqs-met ${PREQS_MET} --root-only NO --weight L --network NO --category security --description \"Check password hashing rounds\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        SHA_CRYPT_MIN_ROUNDS_FIND=$(${GREPBINARY} \"^SHA_CRYPT_MIN_ROUNDS\" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1==\"SHA_CRYPT_MIN_ROUNDS\") { print $2 } }')\n        SHA_CRYPT_MAX_ROUNDS_FIND=$(${GREPBINARY} \"^SHA_CRYPT_MAX_ROUNDS\" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1==\"SHA_CRYPT_MAX_ROUNDS\") { print $2 } }')\n        SHA_CRYPT_ROUNDS=0\n\n        if [ -n \"${SHA_CRYPT_MIN_ROUNDS_FIND}\" -a -n \"${SHA_CRYPT_MAX_ROUNDS_FIND}\" ]; then\n            if [ ${SHA_CRYPT_MIN_ROUNDS_FIND} -lt ${SHA_CRYPT_MAX_ROUNDS_FIND} ]; then\n                SHA_CRYPT_ROUNDS=${SHA_CRYPT_MIN_ROUNDS_FIND}\n            else\n                SHA_CRYPT_ROUNDS=${SHA_CRYPT_MAX_ROUNDS_FIND}\n            fi\n        elif [ -z \"${SHA_CRYPT_MIN_ROUNDS_FIND}\" -a -n \"${SHA_CRYPT_MAX_ROUNDS_FIND}\" ]; then\n            SHA_CRYPT_ROUNDS=${SHA_CRYPT_MAX_ROUNDS_FIND}\n        elif [ -n \"${SHA_CRYPT_MIN_ROUNDS_FIND}\" -a -z \"${SHA_CRYPT_MAX_ROUNDS_FIND}\" ]; then\n            SHA_CRYPT_ROUNDS=${SHA_CRYPT_MIN_ROUNDS_FIND}\n        else\n            SHA_CRYPT_ROUNDS=0\n        fi\n\n        LogText \"Test: Checking SHA_CRYPT_{MIN,MAX}_ROUNDS option in ${ROOTDIR}etc/login.defs\"\n        if [ ${SHA_CRYPT_ROUNDS} -eq 0 ]; then\n            LogText \"Result: number of password hashing rounds is not configured\"\n            Display --indent 2 --text \"- Checking password hashing rounds\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Configure password hashing rounds in /etc/login.defs\"\n            AddHP 0 2\n        fi\n\n        if [ -n \"${SHA_CRYPT_ROUNDS}\" ] && [ ${SHA_CRYPT_ROUNDS} -gt 0 ]; then\n            if [ ${SHA_CRYPT_ROUNDS} -lt 5000 ]; then\n                LogText \"Result: low number of password hashing rounds found: ${SHA_CRYPT_ROUNDS}\"\n                Display --indent 2 --text \"- Password hashing rounds (minimum)\"  --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                AddHP 1 2\n            else\n                LogText \"Result: number of password hashing rounds is ${SHA_CRYPT_ROUNDS}\"\n                Display --indent 2 --text \"- Password hashing rounds (minimum)\" --result CONFIGURED --color GREEN\n                AddHP 2 2\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9234\n    # Description : Query user accounts\n    # Notes       : AIX: 100+\n    #               HPUX: 100+\n    #               macOS doesn't have any user info in /etc/passwd, users are managed with opendirectoryd)\n    #               OpenBSD/NetBSD: 1000-60000, excluding 32767 (default)\n    #               Arch Linux / CentOS / Ubuntu: 1000+\n    Register --test-no AUTH-9234 --weight L --network NO --category security --description \"Query user accounts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Read system users (including root user) from password database (e.g. /etc/passwd)\"\n        FIND=\"\"\n\n        case ${OS} in\n            \"AIX\")\n                LogText \"AIX real users output (ID = 0, or 100+):\"\n                FIND=$(${AWKBINARY} -F: '($3 >= 100 && $3 != 65534) || ($3 == 0) { print $1\",\"$3 }' /etc/passwd)\n            ;;\n\n            \"FreeBSD\")\n                LogText \"FreeBSD real users output (ID = 0, or 1000+, but not 65534):\"\n                FIND=$(${AWKBINARY} -F: '($3 >= 1000 && $3 != 65534) || ($3 == 0) { print $1\",\"$3 }' /etc/passwd)\n            ;;\n\n            \"Linux\")\n                UID_MIN=\"\"\n                if [ -f ${ROOTDIR}etc/login.defs ]; then\n                    UID_MIN=$(${GREPBINARY} \"^UID_MIN\" /etc/login.defs | ${AWKBINARY} '{print $2}')\n                    LogText \"Result: found minimal user id specified: ${UID_MIN}\"\n                fi\n                if [ \"${UID_MIN}\" = \"\" ]; then UID_MIN=\"1000\"; fi\n                LogText \"Linux real users output (ID = 0, or ${UID_MIN}+, but not 65534):\"\n                FIND=$(${AWKBINARY} -v UID_MIN=\"${UID_MIN}\" -F: '($3 >= UID_MIN && $3 != 65534) || ($3 == 0) { print $1\",\"$3 }' /etc/passwd)\n            ;;\n\n            \"macOS\")\n                LogText \"macOS real users output (ID = 0, or 500-599) using dscacheutil\"\n                FIND_USERS=$(dscacheutil -q user | ${GREPBINARY} -A 3 -B 2 -e \"^uid: 5[0-9][0-9]\" | ${GREPBINARY} \"^name: \" | ${AWKBINARY} '{print $2}')\n                if [ -n \"${FIND_USERS}\" ]; then\n                    for FUSERNAME in ${FIND_USERS}; do\n                        FDETAILS=$(dscacheutil -q user -a name ${FUSERNAME} | ${GREPBINARY} \"^uid: \" | ${AWKBINARY} '{print $2}')\n                        FIND=\"${FUSERNAME},${FDETAILS} ${FIND}\"\n                    done\n                else\n                    FIND=\"\"\n                fi\n            ;;\n\n            \"NetBSD\"|\"OpenBSD\")\n                if [ -f ${ROOTDIR}etc/usermgmt.conf ]; then\n                    UID_RANGE=$(${GREPBINARY} \"^range\" ${ROOTDIR}etc/usermgmt.conf | ${AWKBINARY} '{ sub(/\\.\\./, \"-\", $2); print $2 }')\n                fi\n                if [ -n \"${UID_RANGE}\" ]; then\n                    LogText \"Result: found configured user id range specified: ${UID_RANGE}\"\n                    UID_MIN=$(echo $UID_RANGE | ${AWKBINARY} -F- '{ print $1 }')\n                    UID_MAX=$(echo $UID_RANGE | ${AWKBINARY} -F- '{ print $2 }')\n                else\n                    UID_MIN=1000\n                    UID_MAX=60000\n                    LogText \"Result: no configured user id range specified; using default ${UID_MIN}-${UID_MAX}\"\n                fi\n                LogText \"${OS} real users output (ID = 0, or ${UID_MIN}-${UID_MAX}, but not 32767):\"\n                FIND=$(${AWKBINARY} -v UID_MIN=\"${UID_MIN}\" -v UID_MAX=\"${UID_MAX}\" -F: '($3 >= UID_MIN && $3 <= UID_MAX && $3 != 32767) || ($3 == 0) { print $1\",\"$3 }' /etc/passwd)\n            ;;\n\n            \"Solaris\")\n                LogText \"Solaris real users output (ID =0, or 100+, but not 60001/65534):\"\n                FIND=$(${AWKBINARY} -F: '($3 >= 100 && $3 != 60001 && $3 != 65534) || ($3 == 0) { print $1\",\"$3 }' /etc/passwd)\n            ;;\n\n            *)\n                # Want to help improving Lynis? Determine what user IDs belong to normal user accounts\n                ReportException \"${TEST_NO}:1\" \"Can not determine user accounts\"\n            ;;\n        esac\n\n        # Check if we got any output\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 4 --text \"Result: No users found/unknown result\"\n            LogText \"Result: Querying of system users skipped\"\n            Display --indent 2 --text \"- Query system users (non daemons)\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        else\n            Display --indent 2 --text \"- Query system users (non daemons)\" --result \"${STATUS_DONE}\" --color GREEN\n            for I in ${FIND}; do\n                if [ -n \"${I}\" ]; then\n                    LogText \"Real user: ${I}\"\n                    Report \"real_user[]=${I}\"\n                fi\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9240\n    # Description : Query NIS+ authentication support\n    Register --test-no AUTH-9240 --weight L --network NO --category security --description \"Query NIS+ authentication support\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f /etc/nsswitch.conf ]; then\n            FIND=$(${GREPBINARY} -E \"^passwd\" /etc/nsswitch.conf | ${GREPBINARY} -E \"compat|nisplus\")\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: NIS+ authentication not enabled\"\n                Display --indent 2 --text \"- NIS+ authentication support\" --result \"${STATUS_NOT_ENABLED}\" --color WHITE\n            else\n                FIND2=$(${GREPBINARY} -E \"^passwd_compat\" ${ROOTDIR}etc/nsswitch.conf | ${GREPBINARY} \"nisplus\")\n                FIND3=$(${GREPBINARY} -E \"^passwd\" ${ROOTDIR}etc/nsswitch.conf | ${GREPBINARY} \"nisplus\")\n                if [ -n \"${FIND2}\" -o -n \"${FIND3}\" ]; then\n                    LogText \"Result: NIS+ authentication enabled\"\n                    Display --indent 2 --text \"- NIS+ authentication support\" --result \"${STATUS_ENABLED}\" --color GREEN\n                else\n                    LogText \"Result: NIS+ authentication not enabled\"\n                    Display --indent 2 --text \"- NIS+ authentication support\" --result \"${STATUS_NOT_ENABLED}\" --color WHITE\n                fi\n            fi\n          else\n            LogText \"Result: /etc/nsswitch.conf not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9242\n    # Description : Query NIS authentication support\n    Register --test-no AUTH-9242 --weight L --network NO --category security --description \"Query NIS authentication support\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f /etc/nsswitch.conf ]; then\n            FIND=$(${GREPBINARY} -E \"^passwd\" /etc/nsswitch.conf | ${GREPBINARY} -E \"compat|nis\" | ${GREPBINARY} -v \"nisplus\")\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: NIS authentication not enabled\"\n                Display --indent 2 --text \"- NIS authentication support\" --result \"${STATUS_NOT_ENABLED}\" --color WHITE\n            else\n                FIND2=$(${GREPBINARY} -E \"^passwd_compat\" /etc/nsswitch.conf | ${GREPBINARY} \"nis\" | ${GREPBINARY} -v \"nisplus\")\n                FIND3=$(${GREPBINARY} -E \"^passwd\" /etc/nsswitch.conf | ${GREPBINARY} \"nis\" | ${GREPBINARY} -v \"nisplus\")\n                if [ -n \"${FIND2}\" -o -n \"${FIND3}\" ]; then\n                    LogText \"Result: NIS authentication enabled\"\n                    Display --indent 2 --text \"- NIS authentication support\" --result \"${STATUS_ENABLED}\" --color GREEN\n                else\n                    LogText \"Result: NIS authentication not enabled\"\n                    Display --indent 2 --text \"- NIS authentication support\" --result \"${STATUS_NOT_ENABLED}\" --color WHITE\n                fi\n            fi\n        else\n            LogText \"Result: /etc/nsswitch.conf not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9250\n    # Description : Check for sudoers file\n    Register --test-no AUTH-9250 --weight L --network NO --category security --description \"Checking sudoers file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for I in ${SUDOERS_LOCATIONS}; do\n            LogText \"Test: checking presence ${I}\"\n            if [ -f ${I} ]; then\n                FOUND=1\n                SUDOERS_FILE=\"${I}\"\n                LogText \"Result: found file (${SUDOERS_FILE})\"\n            else\n                LogText \"Result: file ${I} not found\"\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: sudoers file found (${SUDOERS_FILE})\"\n            Display --indent 2 --text \"- Sudoers file(s)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: sudoers file NOT found\"\n            Display --indent 2 --text \"- Sudoers file\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9252\n    # Description : Check ownership and permissions for sudo configuration files\n    if [ -n \"${SUDOERS_FILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9252 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description \"Check ownership and permissions for sudo configuration files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        SUDO_CONFIG_FILES=\"${SUDOERS_FILE}\"\n        SUDOERS_D=\"${SUDOERS_FILE}.d\"\n        if [ -d \"${SUDOERS_D}\" ]; then\n            LogText \"Test: checking drop-in directory (${SUDOERS_D})\"\n            FIND=$(${LSBINARY} -ld ${SUDOERS_D} | ${CUTBINARY} -c 2-10)\n            FIND2=$(${LSBINARY} -lnd ${SUDOERS_D} | ${AWKBINARY} '{print $3$4}')\n            LogText \"Result: Found directory permissions: ${FIND} and owner UID GID: ${FIND2}\"\n            case \"${FIND}\" in\n                rwx[r-][w-][x-]--- )\n                    LogText \"Result: directory ${SUDOERS_D} permissions OK\"\n                    if [ \"${FIND2}\" = \"00\" ]; then\n                        LogText \"Result: directory ${SUDOERS_D} ownership OK\"\n                        Display --indent 4 --text \"- Permissions for directory: ${SUDOERS_D}\" --result \"${STATUS_OK}\" --color GREEN\n                    else\n                        LogText \"Result: directory ${SUDOERS_D} has possibly unsafe ownership\"\n                        Display --indent 4 --text \"- Permissions for directory: ${SUDOERS_D}\" --result \"${STATUS_WARNING}\" --color RED\n                    fi\n                    ;;\n                * )\n                    LogText \"Result: directory ${SUDOERS_D} has possibly unsafe permissions\"\n                    if [ \"${FIND2}\" = \"00\" ]; then\n                        LogText \"Result: directory ${SUDOERS_D} ownership OK\"\n                    else\n                        LogText \"Result: directory ${SUDOERS_D} has possibly unsafe ownership\"\n                    fi\n                    Display --indent 4 --text \"- Permissions for directory: ${SUDOERS_D}\" --result \"${STATUS_WARNING}\" --color RED\n                    ;;\n            esac\n            SUDO_CONFIG_FILES=\"${SUDO_CONFIG_FILES} $(${FINDBINARY} -L ${SUDOERS_D} -type f -print)\"\n        fi\n        for f in ${SUDO_CONFIG_FILES}; do\n            LogText \"Test: checking file (${f})\"\n            FIND=$(${LSBINARY} -l ${f} | ${CUTBINARY} -c 2-10)\n            FIND2=$(${LSBINARY} -ln ${f} | ${AWKBINARY} '{print $3$4}')\n            LogText \"Result: Found file permissions: ${FIND} and owner UID GID: ${FIND2}\"\n            case \"${FIND}\" in\n                r[w-]-[r-][w-]---- )\n                    LogText \"Result: file ${f} permissions OK\"\n                    if [ \"${FIND2}\" = \"00\" ]; then\n                        LogText \"Result: file ${f} ownership OK\"\n                        Display --indent 4 --text \"- Permissions for: ${f}\" --result \"${STATUS_OK}\" --color GREEN\n                    else\n                        LogText \"Result: file ${f} has possibly unsafe ownership\"\n                        Display --indent 4 --text \"- Permissions for: ${f}\" --result \"${STATUS_WARNING}\" --color RED\n                    fi\n                    ;;\n                * )\n                    LogText \"Result: file ${f} has possibly unsafe permissions\"\n                    if [ \"${FIND2}\" = \"00\" ]; then\n                        LogText \"Result: file ${f} ownership OK\"\n                    else\n                        LogText \"Result: file ${f} has possibly unsafe ownership\"\n                    fi\n                    Display --indent 4 --text \"- Permissions for: ${f}\" --result \"${STATUS_WARNING}\" --color RED\n                    ;;\n            esac\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9254\n    # Description : Solaris test to check passwordless accounts\n    Register --test-no AUTH-9254 --os Solaris --weight L --network NO --root-only YES --category security --description \"Solaris passwordless accounts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(logins -p | ${AWKBINARY} '{ print $1 }')\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: no passwordless accounts found\"\n            Display --indent 2 --text \"- Passwordless accounts on Solaris\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            for I in ${FIND}; do\n                ReportWarning \"${TEST_NO}\" \"Found passwordless account (${I})\"\n            done\n            Display --indent 2 --text \"- Passwordless accounts on Solaris\" --result \"${STATUS_WARNING}\" --color RED\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9262\n    # Description : Search for PAM password strength testing libraries\n    Register --test-no AUTH-9262 --weight L --network NO --category security --description \"Checking presence password strength testing tools (PAM)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        FOUND_CRACKLIB=0\n        FOUND_PASSWDQC=0\n        FOUND_PWQUALITY=0\n\n        # Cracklib\n        LogText \"Searching PAM password testing modules (cracklib, passwdqc, pwquality)\"\n        for I in ${PAM_FILE_LOCATIONS}; do\n\n            if [ -f ${I}/pam_cracklib.so ]; then\n                FOUND_CRACKLIB=1\n                FOUND=1\n                LogText \"Result: found pam_cracklib.so (crack library PAM) in ${I}\"\n            fi\n\n            if [ -f ${I}/pam_passwdqc.so ]; then\n                FOUND_PASSWDQC=1\n                FOUND=1\n                LogText \"Result: found pam_passwdqc.so (passwd quality control PAM) in ${I}\"\n            fi\n\n            if [ -f ${I}/pam_pwquality.so ]; then\n                FOUND_PWQUALITY=1\n                FOUND=1\n                LogText \"Result: found pam_pwquality.so (password quality control PAM) in ${I}\"\n            fi\n        done\n\n        # Cracklib\n        if [ ${FOUND_CRACKLIB} -eq 1 ]; then\n            LogText \"Result: pam_cracklib.so found\"\n            Report \"pam_cracklib=1\"\n        else\n            LogText \"Result: pam_cracklib.so NOT found (crack library PAM)\"\n        fi\n\n        # Password quality control\n        if [ ${FOUND_PASSWDQC} -eq 1 ]; then\n            LogText \"Result: pam_passwdqc.so found\"\n            Report \"pam_passwdqc=1\"\n        else\n            LogText \"Result: pam_passwdqc.so NOT found (passwd quality control PAM)\"\n        fi\n\n        # pwquality module\n        if [ ${FOUND_PWQUALITY} -eq 1 ]; then\n            LogText \"Result: pam_pwquality.so found\"\n            Report \"pam_pwquality=1\"\n        else\n            LogText \"Result: pam_pwquality.so NOT found (pwquality control PAM)\"\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            Display --indent 2 --text \"- PAM password strength tools\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: no PAM modules for password strength testing found\"\n            ReportSuggestion \"${TEST_NO}\" \"Install a PAM module for password strength testing like pam_cracklib or pam_passwdqc or libpam-passwdqc\"\n            AddHP 0 3\n        else\n            Display --indent 2 --text \"- PAM password strength tools\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: found at least one PAM module for password strength testing\"\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9264\n    # Description : Scan /etc/pam.conf file\n    Register --test-no AUTH-9264 --weight L --network NO --category security --description \"Checking presence pam.conf\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking file /etc/pam.conf\"\n        if [ -f ${ROOTDIR}etc/pam.conf ]; then\n            LogText \"Result: file ${ROOTDIR}etc/pam.conf exists\"\n            Display --indent 2 --text \"- PAM configuration files (pam.conf)\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Test: searching PAM configuration files\"\n            FIND=$(${GREPBINARY} -E -v \"^#\" ${ROOTDIR}etc/pam.conf | ${GREPBINARY} -E -v \"^$\" | ${SEDBINARY} 's/[[:space:]]/ /g' | ${SEDBINARY} 's/  / /g' | ${SEDBINARY} 's/ /:space:/g')\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: File has no configuration options defined (empty, or only filled with comments and empty lines)\"\n            else\n                LogText \"Result: found one or more configuration lines\"\n                for LINE in ${FIND}; do\n                    LINE=$(echo ${LINE} | ${SEDBINARY} 's/:space:/ /g')\n                    LogText \"Found line: ${LINE}\"\n                done\n            fi\n        else\n            LogText \"Result: file /etc/pam.conf could not be found\"\n            Display --indent 2 --text \"- PAM configuration file (pam.conf)\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9266\n    # Description : Searching available PAM configurations (/etc/pam.d)\n    Register --test-no AUTH-9266 --weight L --network NO --category security --description \"Checking presence pam.d files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking directory ${ROOTDIR}etc/pam.d\"\n        if [ -d ${ROOTDIR}etc/pam.d ]; then\n            LogText \"Result: directory /etc/pam.d exists\"\n            Display --indent 2 --text \"- PAM configuration files (pam.d)\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Test: searching PAM configuration files\"\n            FIND=$(${FINDBINARY} -L ${ROOTDIR}etc/pam.d \\! -name \"*.pam-old\" -type f -print | sort)\n            for FILE in ${FIND}; do\n                LogText \"Found file: ${FILE}\"\n            done\n        else\n            LogText \"Result: directory /etc/pam.d could not be found\"\n            Display --indent 2 --text \"- PAM configuration files (pam.d)\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9268\n    # Description : Searching available PAM files\n    # Notes       : PAM is used on AIX, FreeBSD, Linux, HPUX, NetBSD, Solaris\n    OS_USES_PAM=\"AIX DragonFly FreeBSD Linux HPUX NetBSD Solaris\"\n    Register --test-no AUTH-9268 --os \"${OS_USES_PAM}\" --weight L --network NO --category security --description \"Checking presence pam.d files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: Searching pam modules\"\n        for DIR in ${PAM_FILE_LOCATIONS}; do\n            LogText \"Test: Checking ${DIR}\"\n            if [ -d ${DIR} -a ! -L ${DIR} ]; then\n                LogText \"Result: directory ${DIR} exists\"\n                # Search in the specified directory\n                if [ \"${OS}\" = \"AIX\" -o \"${OS}\" = \"Solaris\" ]; then\n                    # AIX/Solaris does not support -maxdepth\n                    FIND=$(find ${DIR} -type f -name \"pam_*.so\" -print | sort)\n                else\n                    FIND=$(find ${DIR} -maxdepth 1 -type f -name \"pam_*.so\" -print | sort)\n                fi\n                if [ -n \"${FIND}\" ]; then FOUND=1; fi\n                for FILE in ${FIND}; do\n                    LogText \"Found file: ${FILE}\"\n                    Report \"pam_module[]=${FILE}\"\n                done\n            else\n                LogText \"Result: directory ${DIR} could not be found or is a symlink to another directory\"\n            fi\n        done\n        # Check if we found at least one module\n        if [ ${FOUND} -eq 0 ]; then\n            Display --indent 2 --text \"- PAM modules\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: no PAM modules found\"\n        else\n            Display --indent 2 --text \"- PAM modules\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n        unset DIR FILE FIND\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9278\n    # Description : Search LDAP support in PAM files\n    Register --test-no AUTH-9278 --weight L --network NO --category security --description \"Determine LDAP support in PAM files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        AUTH_FILES=\"${ROOTDIR}etc/pam.d/common-auth ${ROOTDIR}etc/pam.d/system-auth\"\n        for FILE in ${AUTH_FILES}; do\n            LogText \"Test: checking presence ${FILE}\"\n            if [ -f ${FILE} ]; then\n                LogText \"Result: file ${FILE} exists\"\n                LogText \"Test: checking presence LDAP module\"\n                FIND=$(${GREPBINARY} \"^auth.*ldap\" ${FILE})\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: LDAP module present\"\n                    LogText \"Output: ${FIND}\"\n                    LDAP_AUTH_ENABLED=1\n                    LDAP_PAM_ENABLED=1\n                else\n                    LogText \"Result: LDAP module not found\"\n                fi\n            else\n                LogText \"Result: file ${FILE} not found, skipping test\"\n            fi\n        done\n\n        if [ ${LDAP_PAM_ENABLED} -eq 1 ]; then\n            Display --indent 2 --text \"- LDAP module in PAM\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            Display --indent 2 --text \"- LDAP module in PAM\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9282, AUTH-9283, and AUTH-9284\n    # Note        : Every Linux based operating system seem to have different passwd\n    #               options, so we have to check the version first.\n    if [ \"${OS}\" = \"Linux\" ]; then\n        if [ \"${OS_REDHAT_OR_CLONE}\" -eq 0 ]; then\n            case ${LINUX_VERSION} in\n                \"SuSE\")\n                    PREQS_MET=\"YES\"\n                    FIND_P=$(passwd -a -S 2> /dev/null | ${AWKBINARY} '{ if ($2==\"P\" && $5==\"99999\") print $1 }')\n                    FIND2=$(passwd -a -S 2> /dev/null | ${AWKBINARY} '{ if ($2==\"NP\") print $1 }')\n                    FIND3=$(passwd -a -S 2> /dev/null | ${AWKBINARY} '{ if ($2==\"L\") print $1 }' | sort | uniq)\n                    ;;\n                *)\n                    PREQS_MET=\"YES\"\n                    FIND_P=$(passwd --all --status 2> /dev/null | ${AWKBINARY} '{ if ($2==\"P\" && $5==\"99999\") print $1 }')\n                    FIND2=$(passwd --all --status 2> /dev/null | ${AWKBINARY} '{ if ($2==\"NP\") print $1 }')\n                    FIND3=$(passwd --all --status 2> /dev/null | ${AWKBINARY} '{ if ($2==\"L\") print $1 }' | sort | uniq)\n                    ;;\n            esac\n        elif [ \"${OS_REDHAT_OR_CLONE}\" -eq 1 ]; then\n            PREQS_MET=\"YES\"\n            FIND_P=$(for I in $(${AWKBINARY} -F: '{print $1}' \"${ROOTDIR}etc/passwd\") ; do passwd -S \"$I\" | ${AWKBINARY} '{ if ($2==\"PS\" && $5==\"99999\") print $1 }' ; done)\n            FIND2=$(for I in $(${AWKBINARY} -F: '{print $1}' \"${ROOTDIR}etc/passwd\") ; do passwd -S \"$I\" | ${AWKBINARY} '{ if ($2==\"NP\") print $1 }' ; done)\n            FIND3=$(for I in $(${AWKBINARY} -F: '{print $1}' \"${ROOTDIR}etc/passwd\") ; do passwd -S \"$I\" | ${AWKBINARY} '{ if ($2==\"L\" || $2==\"LK\") print $1 }' | sort | uniq ; done)\n        else\n            LogText \"Result: skipping test for this Linux version\"\n            ReportManual \"AUTH-9282:01\"\n            PREQS_MET=\"NO\"\n            FIND_P=\"\"\n            FIND2=\"\"\n            FIND3=\"\"\n        fi\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    # Test        : AUTH-9282\n    # Description : Search password protected accounts without expire (Linux)\n    Register --test-no AUTH-9282 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking password protected account without expire date\"\n    if [ \"${SKIPTEST}\" -eq 0 ]; then\n        LogText \"Test: Checking Linux version and password expire date status\"\n        if [ -z \"${FIND_P}\" ]; then\n            LogText \"Result: all accounts seem to have an expire date\"\n            Display --indent 2 --text \"- Accounts without expire date\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: found one or more accounts without expire date set\"\n            for I in ${FIND_P}; do\n                LogText \"Account without expire date: ${I}\"\n            done\n            Display --indent 2 --text \"- Accounts without expire date\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"When possible set expire dates for all password protected accounts\"\n        fi\n    fi\n\n    # Test        : AUTH-9283\n    # Description : Search passwordless accounts\n    # Notes       : requires FIND2 variable\n    Register --test-no AUTH-9283 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking accounts without password\"\n    if [ \"${SKIPTEST}\" -eq 0 ]; then\n        LogText \"Test: Checking passwordless accounts\"\n        if [ -z \"${FIND2}\" ]; then\n            LogText \"Result: all accounts seem to have a password\"\n            Display --indent 2 --text \"- Accounts without password\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: found one or more accounts without password\"\n            for I in ${FIND2}; do\n                LogText \"Account without password: ${I}\"\n                Report \"account_without_password[]=${I}\"\n            done\n            Display --indent 2 --text \"- Accounts without password\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Found accounts without password\"\n        fi\n    fi\n\n    # Test        : AUTH-9284\n    # Description : Check locked user accounts in /etc/passwd\n    # Notes       : requires FIND3 variable\n    Register --test-no AUTH-9284 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check locked user accounts in /etc/passwd\"\n    if [ \"${SKIPTEST}\" -eq 0 ]; then\n        LogText \"Test: Checking locked accounts\"\n        NON_SYSTEM_ACCOUNTS=$(${AWKBINARY} -F : '$3 > 999 && $3 != 65534 {print $1}' ${ROOTDIR}etc/passwd | ${SORTBINARY} | ${UNIQBINARY})\n        LOCKED_NON_SYSTEM_ACCOUNTS=0\n        for account in ${FIND3}; do\n            if echo \"${NON_SYSTEM_ACCOUNTS}\" | ${GREPBINARY} -w \"${account}\" > /dev/null ; then\n                LOCKED_NON_SYSTEM_ACCOUNTS=$((LOCKED_NON_SYSTEM_ACCOUNTS + 1))\n            fi\n        done\n        if [ ${LOCKED_NON_SYSTEM_ACCOUNTS} -eq 0 ]; then\n            LogText \"Result: all accounts seem to be unlocked\"\n            Display --indent 2 --text \"- Locked accounts\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: found one or more locked accounts\"\n            for account in ${FIND3}; do\n                if echo \"${NON_SYSTEM_ACCOUNTS}\" | ${GREPBINARY} -w \"${account}\" > /dev/null ; then\n                    LogText \"Locked account: ${account}\"\n                    Report \"locked_account[]=${account}\"\n                fi\n            done\n            Display --indent 2 --text \"- Locked accounts\" --result \"${STATUS_FOUND}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Look at the locked accounts and consider removing them\"\n        fi\n        unset account LOCKED_NON_SYSTEM_ACCOUNTS NON_SYSTEM_ACCOUNTS\n    fi\n\n    unset FIND1 FIND2 FIND3\n#\n#################################################################################\n#\n    # Test        : AUTH-9286\n    # Description : Check user password aging\n    # Notes       : MIN = minimum age, avoid rotation of passwords too quickly\n    #             : MAX = maximum age, ensure regular change of passwords\n    PREQS_MET=\"NO\"\n    if [ -f ${ROOTDIR}etc/login.defs ]; then\n        PREQS_MET=\"YES\"\n        # Future TODO: check if PAM overrule these settings\n    fi\n    Register --test-no AUTH-9286 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking user password aging\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking PASS_MIN_DAYS option in ${ROOTDIR}etc/login.defs\"\n        FIND=$(${GREPBINARY} \"^PASS_MIN_DAYS\" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1==\"PASS_MIN_DAYS\") { print $2 } }')\n        if [ -z \"${FIND}\" -o \"${FIND}\" = \"0\" ]; then\n            LogText \"Result: password minimum age is not configured\"\n            Display --indent 2 --text \"- Checking user password aging (minimum)\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Configure minimum password age in /etc/login.defs\"\n            AddHP 0 1\n        else\n            LogText \"Result: password needs to be at least ${FIND} days old\"\n            PASSWORD_MINIMUM_DAYS=${FIND}\n            Display --indent 2 --text \"- User password aging (minimum)\" --result CONFIGURED --color GREEN\n            AddHP 3 3\n        fi\n\n        LogText \"Test: Checking PASS_MAX_DAYS option in ${ROOTDIR}etc/login.defs \"\n        FIND=$(${GREPBINARY} \"^PASS_MAX_DAYS\" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1==\"PASS_MAX_DAYS\") { print $2 } }')\n        if [ -z \"${FIND}\" -o \"${FIND}\" = \"99999\" ]; then\n            LogText \"Result: password aging limits are not configured\"\n            Display --indent 2 --text \"- User password aging (maximum)\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Configure maximum password age in /etc/login.defs\"\n            AddHP 0 1\n        else\n            LogText \"Result: max password age is ${FIND} days\"\n            PASSWORD_MAXIMUM_DAYS=${FIND}\n            Display --indent 2 --text \"- User password aging (maximum)\" --result CONFIGURED --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9288\n    # Description : Determine which accounts have an expired password\n    # Notes       : This test might not work (yet) on all platforms\n    if [ -f ${ROOTDIR}etc/shadow ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9288 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description \"Checking for expired passwords\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if FileIsReadable ${ROOTDIR}etc/shadow; then\n\n            if [ \"${OS}\" = \"Solaris\" ]; then\n                NOW=$(nawk 'BEGIN{print srand()}')\n            else\n                NOW=$(date \"+%s\")\n            fi\n\n            DAYS_SINCE_EPOCH=$((NOW / 86400))\n            LogText \"Data: Days since epoch is ${DAYS_SINCE_EPOCH}\"\n            LogText \"Test: collecting accounts which have an expired password (last day changed + maximum change time)\"\n            # Skip fields with a !, *, or x, or !* (field $3 is last changed, $5 is maximum changed)\n            FIND=$(${GREPBINARY} -E -v \":[\\!\\*x]([\\*\\!])?:\" /etc/shadow | ${AWKBINARY} -v today=${DAYS_SINCE_EPOCH} -F: '{ if (($5!=\"\") && (today>$3+$5)) { print $1 }}')\n            if [ -n \"${FIND}\" ]; then\n                for ACCOUNT in ${FIND}; do\n                    LogText \"Result: password of user ${ACCOUNT} has been expired\"\n                    Report \"account_password_expired[]=${ACCOUNT}\"\n                done\n                AddHP 0 10\n                Display --indent 2 --text \"- Checking expired passwords\" --result \"${STATUS_FOUND}\" --color RED\n                ReportSuggestion \"${TEST_NO}\" \"Delete accounts which are no longer used\"\n            else\n                LogText \"Result: good, no passwords have been expired\"\n                Display --indent 2 --text \"- Checking expired passwords\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 10 10\n            fi\n        else\n            Display --indent 2 --text \"- Checking expired passwords\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9304\n    # Description : Check if single user mode login is properly configured in Solaris\n    # Notes       : sulogin should be called from svm script (Solaris <10) in /etc/rcS.d\n    Register --test-no AUTH-9304 --os Solaris --weight L --network NO --category security --description \"Check single user login configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if file exists (Solaris 10 does not have this file by default)\n        if [ -f ${ROOTDIR}etc/default/sulogin ]; then\n            LogText \"Result: file ${ROOTDIR}etc/default/sulogin exists\"\n            LogText \"Test: checking presence PASSREQ=NO\"\n            FIND=$(${GREPBINARY} \"^PASSREQ=NO\" ${ROOTDIR}etc/default/sulogin)\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: option not present or configured to request a password at single user mode login\"\n                Display --indent 2 --text \"- Checking Solaris /etc/default/sulogin file\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 1 1\n            else\n                LogText \"Result: option present, no password needed at single user mode login\"\n                Display --indent 2 --text \"- Checking Solaris /etc/default/sulogin file\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"No password needed for single user mode login\"\n                AddHP 0 1\n            fi\n        else\n            LogText \"Result: file /etc/default/sulogin does not exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9306\n    # Description : Check if authentication is needed to boot the system\n    # Notes       : :d_boot_authenticate: is a good option for production machines to\n    #               avoid unauthorized booting of systems. Option :d_boot_authentication@:\n    #               disabled a required login.\n    Register --test-no AUTH-9306 --os HP-UX --weight L --network NO --category security --description \"Check single boot authentication\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if file exists\n        LogText \"Test: Searching /tcb/files/auth/system/default\"\n        if [ -f ${ROOTDIR}tcb/files/auth/system/default ]; then\n            LogText \"Result: file ${ROOTDIR}tcb/files/auth/system/default exists\"\n            LogText \"Test: checking presence :d_boot_authenticate@:\"\n            FIND=$(${GREPBINARY} \"^:d_boot_authenticate@\" /tcb/files/auth/system/default)\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: option not set, password is needed at boot\"\n                Display --indent 2 --text \"- Checking HP-UX boot authentication\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 1 1\n            else\n                LogText \"Result: option present, no password needed at single user mode login\"\n                Display --indent 2 --text \"- Checking HP-UX boot authentication\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Set password for system boot\"\n                AddHP 0 1\n            fi\n        else\n            LogText \"Result: file ${ROOTDIR}tcb/files/auth/system/default does not exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9308\n    # Description : Check single user mode login for Linux\n    Register --test-no AUTH-9308 --os Linux --weight L --network NO --category security --description \"Check single user login configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        TEST_PERFORMED=0\n\n        if [ ${HAS_SYSTEMD} -eq 0 ]; then\n            # Check inittab\n            LogText \"Test: Searching ${ROOTDIR}etc/inittab\"\n            if [ -f ${ROOTDIR}etc/inittab ]; then\n                TEST_PERFORMED=1\n                LogText \"Result: file ${ROOTDIR}etc/inittab exists\"\n                LogText \"Test: checking presence sulogin for single user mode\"\n                FIND=$(${GREPBINARY} -E \"^[a-zA-Z0-9~]+:S:(respawn|wait):/sbin/sulogin\" /etc/inittab)\n                FIND2=$(${GREPBINARY} -E \"^su:S:(respawn|wait):/sbin/sulogin\" /etc/inittab)\n                if [ -n \"${FIND}\" -o -n \"${FIND2}\" ]; then\n                    FOUND=1\n                    LogText \"Result: found sulogin, so single user is protected\"\n                fi\n            else\n                LogText \"Result: file ${ROOTDIR}etc/inittab does not exist\"\n            fi\n\n            # Check init\n            LogText \"Test: Searching ${ROOTDIR}etc/sysconfig/init\"\n            if [ -f ${ROOTDIR}etc/sysconfig/init ]; then\n                TEST_PERFORMED=1\n                LogText \"Result: file ${ROOTDIR}etc/sysconfig/init exists\"\n                LogText \"Test: checking presence sulogin for single user mode\"\n                FIND=$(${GREPBINARY} \"^SINGLE=/sbin/sulogin\" ${ROOTDIR}etc/sysconfig/init)\n                if [ -n \"${FIND}\" ]; then\n                    FOUND=1\n                    LogText \"Result: found sulogin, so single user is protected\"\n                fi\n            else\n                LogText \"Result: file ${ROOTDIR}etc/sysconfig/init does not exist\"\n            fi\n        fi\n\n        # Systemd support\n        SYSTEMD_DIRECTORY=\"/lib/systemd/system\"\n        if [ -d ${SYSTEMD_DIRECTORY} ]; then\n            FILES=\"console-shell.service emergency.service rescue.service\"\n            LogText \"Test: going to check several systemd targets now\"\n            for I in ${FILES}; do\n                FILE=\"${SYSTEMD_DIRECTORY}/${I}\"\n                LogText \"Test: checking if target ${I} is available (${FILE})\"\n                if [ -f ${FILE} ]; then\n                    # Mark test as performed only when at least 1 target exists (e.g. Ubuntu 14.04 has limited systemd support)\n                    TEST_PERFORMED=1\n                    LogText \"Result: found target ${I}\"\n                    FIND=$(${GREPBINARY} -E \"^ExecStart=\" ${FILE} | ${GREPBINARY} \"sulogin\")\n                    if [ \"${FIND}\" = \"\" ]; then\n                        LogText \"Result: did not find sulogin specified, possible risk of getting into single user mode without authentication\"\n                    else\n                        LogText \"Result: sulogin was found, which is a good measure to protect single user mode\"\n                        FOUND=1\n                    fi\n                else\n                    LogText \"Result: target ${I} not found\"\n                fi\n            done\n        fi\n\n        if [ ${TEST_PERFORMED} -eq 1 ]; then\n            if [ ${FOUND} -eq 0 ]; then\n                LogText \"Result: option not set, no password needed at single user mode boot\"\n                Display --indent 2 --text \"- Checking Linux single user mode authentication\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"No password set for single mode\"\n                ReportSuggestion \"${TEST_NO}\" \"Set password for single user mode to minimize physical access attack surface\"\n                AddHP 0 2\n            else\n                LogText \"Result: option set, password is needed at single user mode boot\"\n                Display --indent 2 --text \"- Checking Linux single user mode authentication\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 2 2\n            fi\n        else\n            LogText \"Result: no tests performed\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9328\n    # Description : Check default umask in common files\n    # Notes:        This test should be moved later to shells section\n    # /etc/login.defs\n    # pam_umask\n    Register --test-no AUTH-9328 --weight L --network NO --category security --description \"Default umask values\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Determining default umask\"\n        GOOD_UMASK=0\n        WEAK_UMASK=0\n\n        # /etc/profile.d\n        LogText \"Test: Checking ${ROOTDIR}etc/profile.d directory\"\n        if [ -d ${ROOTDIR}etc/profile.d ]; then\n            FOUND=0\n            FIND=$(ls ${ROOTDIR}etc/profile.d/* 2> /dev/null)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found /etc/profile.d, with one or more files in it\"\n                for FILE in ${FIND}; do\n                    HAS_MASK=$(${GREPBINARY} umask ${FILE} 2> /dev/null | ${SEDBINARY} 's/^[ \\t]*//' | ${GREPBINARY} -v \"^#\" | ${AWKBINARY} '{ print $2 }')\n                    for MASK in ${HAS_MASK}; do\n                        if [ \"${MASK}\" = \"077\" -o \"${MASK}\" = \"027\" -o \"${MASK}\" = \"0077\" -o \"${MASK}\" = \"0027\" ]; then\n                            LogText \"Result: found a strong umask '${MASK}' set in ${FILE}\"\n                            GOOD_UMASK=1\n                        else\n                            LogText \"Result: found a weak umask '${MASK}' set in ${FILE}\"\n                            WEAK_UMASK=1\n                        fi\n                    done\n                done\n            else\n                LogText \"Result: found /etc/profile.d, but it does not contain any files\"\n            fi\n        else\n            LogText \"Result: /etc/profile.d not found\"\n        fi\n\n        # Test /etc/profile (only if we didn't find a good umask in profile.d)\n        LogText \"Test: Checking /etc/profile\"\n        if [ -f /etc/profile -a ${GOOD_UMASK} -eq 0 ]; then\n            LogText \"Result: file /etc/profile exists\"\n            LogText \"Test: Checking umask value in /etc/profile\"\n            FIND=$(${GREPBINARY} \"umask\" /etc/profile | ${SEDBINARY} 's/^[ \\t]*//' | ${GREPBINARY} -v \"^#\" | ${AWKBINARY} '{ print $2 }')\n            FIND2=$(${GREPBINARY} \"umask\" /etc/profile | ${SEDBINARY} 's/^[ \\t]*//' | ${GREPBINARY} -v \"^#\" | ${AWKBINARY} '{ print $2 }' | wc -l)\n            FOUND_UMASK=0\n            if [ \"${FIND2}\" = \"0\" ]; then\n                LogText \"Result: did not find umask in /etc/profile\"\n            elif [ \"${FIND2}\" = \"1\" ]; then\n                LogText \"Result: found umask (prefixed with spaces)\"\n                FOUND_UMASK=1\n                if [ ! \"${FIND}\" = \"077\" -a ! \"${FIND}\" = \"027\" -a ! \"${FIND}\" = \"0077\" -a ! \"${FIND}\" = \"0027\" ]; then\n                    LogText \"Result: found umask ${FIND}, which could be more strict\"\n                    WEAK_UMASK=1\n                else\n                    LogText \"Result: found umask ${FIND}, which is fine\"\n                    GOOD_UMASK=1\n                fi\n              # Found more than 1 umask value in profile\n            else\n                LogText \"Result: found multiple umask values configured in /etc/profile\"\n                FOUND_UMASK=1\n                for I in ${FIND}; do\n                    if [ ! \"${I}\" = \"077\" -a ! \"${I}\" = \"027\" -a ! \"${I}\" = \"0077\" -a ! \"${I}\" = \"0027\" ]; then\n                        LogText \"Result: umask ${I} could be more strict\"\n                        WEAK_UMASK=1\n                        AddHP 1 2\n                    else\n                        LogText \"Result: Found umask ${I}, which is fine\"\n                        AddHP 2 2\n                    fi\n                done\n            fi\n\n            if [ ${FOUND_UMASK} -eq 1 ]; then\n                if [ ${WEAK_UMASK} -eq 0 ]; then\n                    Display --indent 4 --text \"- umask (/etc/profile and /etc/profile.d)\" --result \"${STATUS_OK}\" --color GREEN\n                    AddHP 2 2\n                elif [ ${GOOD_UMASK} -eq 1 -a ${WEAK_UMASK} -eq 1 ]; then\n                    Display --indent 4 --text \"- umask (/etc/profile and /etc/profile.d)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Some umasks found could be more strict (e.g. 027)\"\n                    AddHP 1 2\n                else\n                    Display --indent 4 --text \"- umask (/etc/profile and /etc/profile.d)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/profile or /etc/profile.d/custom.sh could be more strict (e.g. 027)\"\n                    AddHP 0 2\n                fi\n              else\n                # Some operating systems don't have a default umask defined in /etc/profile (Debian)\n                LogText \"Result: found no umask. Please check if this is correct\"\n                Display --indent 4 --text \"- umask (/etc/profile)\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            fi\n        fi\n\n        # /etc/passwd\n        LogText \"Test: Checking umask entries in /etc/passwd (pam_umask)\"\n        if [ -f /etc/passwd ]; then\n            LogText \"Result: file /etc/passwd exists\"\n            LogText \"Test: Checking umask value in /etc/passwd\"\n            FIND=$(${GREPBINARY} \"umask=\" /etc/passwd)\n            if [ \"${FIND}\" = \"\" ]; then\n                ReportManual \"AUTH-9328:03\"\n            fi\n          else\n            LogText \"Result: file /etc/passwd does not exist\"\n        fi\n\n        # /etc/login.defs\n        LogText \"Test: Checking /etc/login.defs\"\n        if [ -f /etc/login.defs ]; then\n            LogText \"Result: file /etc/login.defs exists\"\n            LogText \"Test: Checking umask value in /etc/login.defs\"\n            FIND=$(${GREPBINARY} \"^UMASK\" /etc/login.defs | ${AWKBINARY} '{ print $2 }')\n            if [ \"${FIND}\" = \"\" ]; then\n                LogText \"Result: umask value is not configured (most likely it will have the default 022 value)\"\n                Display --indent 4 --text \"- umask (/etc/login.defs)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/login.defs could not be found and defaults usually to 022, which could be more strict like 027\"\n                AddHP 1 2\n            elif [ \"${FIND}\" = \"077\" -o \"${FIND}\" = \"027\" -o \"${FIND}\" = \"0077\" -o \"${FIND}\" = \"0027\" ]; then\n                LogText \"Result: umask is ${FIND}, which is fine\"\n                Display --indent 4 --text \"- umask (/etc/login.defs)\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 2 2\n            else\n                LogText \"Result: found umask ${FIND}, which could be improved\"\n                Display --indent 4 --text \"- umask (/etc/login.defs)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/login.defs could be more strict like 027\"\n                AddHP 0 2\n            fi\n        else\n            LogText \"Result: file /etc/login.defs does not exist\"\n        fi\n\n        # Red Hat /etc/init.d/functions\n        LogText \"Test: Checking /etc/init.d/functions\"\n        if [ -f /etc/init.d/functions ]; then\n            LogText \"Result: file /etc/init.d/functions exists\"\n            LogText \"Test: Checking umask value in /etc/init.d/functions\"\n            FIND=$(${GREPBINARY} \"^umask\" /etc/init.d/functions | ${AWKBINARY} '{ print $2 }')\n            if [ \"${FIND}\" = \"\" ]; then\n                LogText \"Result: umask is not configured\"\n                Display --indent 4 --text \"- umask (/etc/init.d/functions)\" --result \"${STATUS_NONE}\" --color WHITE\n            elif [ \"${FIND}\" = \"077\" -o \"${FIND}\" = \"027\" -o \"${FIND}\" = \"0077\" -o \"${FIND}\" = \"0027\" ]; then\n                LogText \"Result: umask is ${FIND}, which is fine\"\n                Display --indent 4 --text \"- umask (/etc/init.d/functions)\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 2 2\n            else\n                LogText \"Result: found umask ${FIND}, which could be improved\"\n                Display --indent 4 --text \"- umask (/etc/init.d/functions)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                AddHP 0 2\n            fi\n        else\n            LogText \"Result: file /etc/init.d/functions does not exist\"\n        fi\n\n        # /etc/init.d/rc\n        LogText \"Test: Checking /etc/init.d/rc\"\n        if [ -f /etc/init.d/rc ]; then\n            LogText \"Result: file /etc/init.d/rc exists\"\n            LogText \"Test: Checking UMASK value in /etc/init.d/rc\"\n            FIND=$(${GREPBINARY} -i \"^UMASK\" /etc/init.d/rc | ${AWKBINARY} '{ print $2 }')\n            if [ \"${FIND}\" = \"\" ]; then\n                LogText \"Result: UMASK value is not configured (most likely it will have the default 022 value)\"\n                Display --indent 4 --text \"- Checking umask (/etc/init.d/rc)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/init.d/rc could not be found and defaults usually to 022, which could be more strict like 027\"\n                AddHP 1 2\n            elif [ \"${FIND}\" = \"077\" -o \"${FIND}\" = \"027\" -o \"${FIND}\" = \"0077\" -o \"${FIND}\" = \"0027\" ]; then\n                LogText \"Result: umask is ${FIND}, which is fine\"\n                Display --indent 4 --text \"- umask (/etc/init.d/rc)\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 2 2\n            else\n                LogText \"Result: found umask ${FIND}, which could be improved\"\n                Display --indent 4 --text \"- umask (/etc/init.d/rc)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/init.d/rc could be more strict like 027\"\n                AddHP 0 2\n            fi\n          else\n            LogText \"Result: file /etc/init.d/rc does not exist\"\n        fi\n\n        # FreeBSD\n        if [ -f /etc/login.conf ]; then\n            FOUND=0\n            WEAK_UMASK=0\n            LogText \"Result: file /etc/login.conf exists\"\n            FIND=$(${GREPBINARY} \"umask\" /etc/login.conf | ${SEDBINARY} 's/#.*//' | ${SEDBINARY} -E 's/^[[:cntrl:]]//' | ${GREPBINARY} -v '^$' | ${AWKBINARY} -F: '{ print $2}' | ${AWKBINARY} -F= '{ if ($1==\"umask\") { print $2 }}')\n            if [ ! \"${FIND}\" = \"\" ]; then\n                for UMASK_VALUE in ${FIND}; do\n                    case ${UMASK_VALUE} in\n                        027|0027|077|0077)\n                            LogText \"Result: found umask value ${UMASK_VALUE}, which is fine\"\n                            AddHP 2 2\n                            FOUND=1\n                        ;;\n                        *)\n                            AddHP 0 2\n                            FOUND=1\n                            WEAK_UMASK=1\n                            LogText \"Result: found umask value ${UMASK_VALUE}, which can be more strict\"\n                        ;;\n                    esac\n                done\n            fi\n            if [ ${FOUND} -eq 1 ]; then\n                if [ ${WEAK_UMASK} -eq 0 ]; then\n                    Display --indent 4 --text \"- umask (/etc/login.conf)\" --result \"${STATUS_OK}\" --color GREEN\n                else\n                    Display --indent 4 --text \"- umask (/etc/login.conf)\" --result \"${STATUS_WEAK}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Umask in /etc/login.conf could be more strict like 027\"\n                fi\n            else\n                LogText \"Result: no umask setting found in /etc/login.conf, which is unexpected\"\n                Display --indent 4 --text \"- umask (/etc/login.conf)\" --result \"${STATUS_NONE}\" --color YELLOW\n            fi\n        fi\n\n        # /etc/init.d/rcS\n        LogText \"Test: Checking /etc/init.d/rcS\"\n        if [ -f /etc/init.d/rcS ]; then\n            LogText \"Result: file /etc/init.d/rcS exists\"\n            LogText \"Test: Checking if script runs another script.\"\n            FIND=$(${GREPBINARY} -i \"^exec \" /etc/init.d/rcS | ${AWKBINARY} '{ print $2 }')\n            if [ \"${FIND}\" = \"\" ]; then\n                FIND2=$(${GREPBINARY} -i \"^UMASK\" /etc/init.d/rcS | ${AWKBINARY} '{ print $2 }')\n                if [ \"${FIND2}\" = \"\" ]; then\n                    LogText \"Result: UMASK value is not configured (most likely it will have the default 022 value)\"\n                    Display --indent 4 --text \"- Checking umask (/etc/init.d/rcS)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/init.d/rcS could not be found and defaults usually to 022, which could be more strict like 027\"\n                    AddHP 1 2\n                elif [ \"${FIND2}\" = \"077\" -o \"${FIND2}\" = \"027\" ]; then\n                    LogText \"Result: umask is ${FIND2}, which is fine\"\n                    Display --indent 4 --text \"- umask (/etc/init.d/rcS)\" --result \"${STATUS_OK}\" --color GREEN\n                    AddHP 2 2\n                else\n                    LogText \"Result: found umask ${FIND2}, which could be improved\"\n                    Display --indent 4 --text \"- umask (/etc/init.d/rcS)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Default umask in /etc/init.d/rcS could be more strict like 027\"\n                    AddHP 0 2\n                fi\n            else\n                # Improve check\n                LogText \"Result: exec line present in file, setting of umask not needed in this script\"\n                LogText \"Output: ${FIND}\"\n            fi\n          else\n            LogText \"Result: file /etc/init.d/rcS does not exist\"\n        fi\n\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9340\n    # Description : Solaris account locking\n    Register --test-no AUTH-9340 --os Solaris --weight L --network NO --category security --description \"Solaris account locking\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        if [ -f ${ROOTDIR}etc/security/policy.conf ]; then\n            LogText \"Result: found ${ROOTDIR}etc/security/policy.conf\"\n            FIND=$(${GREPBINARY} \"^LOCK_AFTER_RETRIES\" /etc/security/policy.conf)\n            if [ ! \"${FIND}\" = \"\" ]; then\n                FOUND=1\n                LogText \"Result: account locking option set\"\n                LogText \"Output: ${FIND}\"\n                AddHP 2 2\n            else\n                LogText \"Result: option LOCK_AFTER_RETRIES not set\"\n                AddHP 1 2\n            fi\n        else\n            LogText \"Result: ${ROOTDIR}etc/security/policy.conf does not exist\"\n        fi\n        # If policy.conf does not exist, we most likely deal with a Solaris version below 10\n        # and we proceed with checking the softer option RETRIES in /etc/default/login\n        # which does not lock account, but discourages brute force password attacks.\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Test: checking ${ROOTDIR}etc/default/login\"\n            if [ -f ${ROOTDIR}etc/default/login ]; then\n                LogText \"Result: file ${ROOTDIR}etc/default/login exists\"\n                FIND=$(${GREPBINARY} \"^RETRIES\" ${ROOTDIR}etc/default/login)\n                if [ -n \"${FIND}\" ]; then\n                    FOUND=1\n                    LogText \"Result: retries option configured\"\n                    LogText \"Output: ${FIND}\"\n                    AddHP 2 2\n                else\n                    LogText \"Result: retries option not configured\"\n                    AddHP 1 2\n                fi\n            else\n                LogText \"Result: file ${ROOTDIR}etc/default/login does not exist\"\n            fi\n        fi\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking account locking\" --result \"${STATUS_ENABLED}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Checking account locking\" --result \"${STATUS_NOT_ENABLED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9402\n    # Description : Query LDAP authentication support\n    Register --test-no AUTH-9402 --weight L --network NO --category security --description \"Query LDAP authentication support\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}etc/nsswitch.conf ]; then\n            FIND=$(${GREPBINARY} -E \"^passwd\" ${ROOTDIR}etc/nsswitch.conf | ${GREPBINARY} \"ldap\")\n            if [ \"${FIND}\" = \"\" ]; then\n                LogText \"Result: LDAP authentication not enabled\"\n                Display --indent 2 --text \"- LDAP authentication support\" --result \"${STATUS_NOT_ENABLED}\" --color WHITE\n            else\n                LogText \"Result: LDAP authentication enabled\"\n                Display --indent 2 --text \"- LDAP authentication support\" --result \"${STATUS_ENABLED}\" --color GREEN\n                LDAP_AUTH_ENABLED=1\n            fi\n        else\n            LogText \"Result: /etc/nsswitch.conf not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9406\n    # Description : Check LDAP servers in client configuration\n    if [ ${LDAP_AUTH_ENABLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9406 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Query LDAP servers in client configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking ldap.conf options\"\n        for FILE in ${LDAP_CONF_LOCATIONS}; do\n            LogText \"Test: checking ${FILE}\"\n            if [ -f ${FILE} ]; then\n                LogText \"Result: file ${FILE} exists, LDAP being used\"\n                LDAP_CLIENT_CONFIG_FILE=\"${FILE}\"\n                LogText \"Test: checking LDAP servers in file ${FILE}\"\n                FIND=$(${GREPBINARY} -E \"^host \" ${FILE} | ${AWKBINARY} '{ print $2 }')\n                for SERVER in ${FIND}; do\n                    Display --indent 6 --text \"LDAP server: ${SERVER}\"\n                    LogText \"Result: found LDAP server ${SERVER}\"\n                    Report \"ldap_server[]=${SERVER}\"\n                done\n            else\n                LogText \"Result: ${FILE} does NOT exist\"\n            fi\n        done\n        unset FILE FIND SERVER\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9408\n    # Description : Logging of failed login attempts\n    Register --test-no AUTH-9408 --weight L --network NO --category security --description \"Logging of failed login attempts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f \"${ROOTDIR}etc/pam.conf\" -o -d \"${ROOTDIR}etc/pam.d\" ]; then\n            FOUND_PAM_TALLY2=0\n            FOUND_TALLYLOG=0\n            FOUND_PAM_FAILLOCK=0\n            FOUND_FAILLOCKDIR=0\n            if [ -d \"${ROOTDIR}var/run/faillock\" ]; then\n                FOUND_FAILLOCKDIR=1\n                LogText \"Result: found ${ROOTDIR}var/run/faillock directory\"\n            elif [ -s \"${ROOTDIR}var/log/tallylog\" ]; then\n                FOUND_TALLYLOG=1\n                LogText \"Result: found ${ROOTDIR}var/log/tallylog with a size bigger than zero\"\n            else\n                LogText \"Result: did not find ${ROOTDIR}var/run/faillock directory or ${ROOTDIR}var/log/tallylog file on disk or its file size is zero bytes\"\n            fi\n            # Determine if pam_faillock is available\n            for D in $(GetReportData --key \"pam_module\\\\\\[\\\\\\]\"); do\n                if ContainsString \"pam_faillock\" \"${D}\"; then\n                    LogText \"Result: found pam_faillock module on disk\"\n                    FOUND_PAM_FAILLOCK=1\n                fi\n            done\n            if [ ${FOUND_PAM_FAILLOCK} -eq 0 ]; then\n                # Determine if pam_tally2 is available\n                for D in $(GetReportData --key \"pam_module\\\\\\[\\\\\\]\"); do\n                    if ContainsString \"pam_tally2\" \"${D}\"; then\n                        LogText \"Result: found pam_tally2 module on disk\"\n                        FOUND_PAM_TALLY2=1\n                    fi\n                done\n            fi\n            if [ ${FOUND_PAM_FAILLOCK} -eq 1 -a ${FOUND_FAILLOCKDIR} -eq 1 ]; then\n                LogText \"Outcome: authentication failures are logged using pam_faillock\"\n                AUTH_FAILED_LOGINS_LOGGED=1\n                Report \"auth_failed_logins_tooling[]=pam_faillock\"\n            elif [ ${FOUND_PAM_TALLY2} -eq 1 -a ${FOUND_TALLYLOG} -eq 1 ]; then\n                LogText \"Outcome: authentication failures are logged using pam_tally2\"\n                AUTH_FAILED_LOGINS_LOGGED=1\n                Report \"auth_failed_logins_tooling[]=pam_tally2\"\n            else\n                LogText \"Outcome: it looks like pam_faillock or pam_tally2 is not configured to log failed login attempts\"\n            fi\n\n            unset FOUND_PAM_TALLY2 FOUND_TALLYLOG FOUND_PAM_FAILLOCK FOUND_FAILLOCKDIR\n        fi\n        # Also check /etc/logins.defs, although its usage decreased over the years\n        if [ -f ${ROOTDIR}etc/login.defs ]; then\n            LogText \"Test: Checking FAILLOG_ENAB option in ${ROOTDIR}etc/login.defs \"\n            FIND=$(${GREPBINARY} \"^FAILLOG_ENAB\" ${ROOTDIR}etc/login.defs | ${AWKBINARY} '{ if ($1==\"FAILLOG_ENAB\") { print $2 } }')\n            # Search for enabled status (yes), otherwise consider it to be disabled (e.g. empty, or other value)\n            if [ \"${FIND}\" = \"yes\" ]; then\n                AUTH_FAILED_LOGINS_LOGGED=1\n                Report \"auth_failed_logins_tooling[]=/etc/login.defs\"\n                LogText \"Result: FAILLOG_ENAB is set to 'yes'\"\n                LogText \"Outcome: failed login attempts are logged in ${ROOTDIR}var/log/faillog\"\n                Display --indent 2 --text \"- Logging failed login attempts\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                LogText \"Result: failed login attempts may not logged\"\n                Display --indent 2 --text \"- Logging failed login attempts\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            fi\n        fi\n\n        if [ ${AUTH_FAILED_LOGINS_LOGGED} -eq 1 ]; then\n            AddHP 3 3\n        else\n            AddHP 0 1\n            #ReportSuggestion \"${TEST_NO}\" \"Configure failed login attempts to be logged using pam_tally2 or /etc/login.defs\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9409\n    # Description : Check for doas file\n    DOAS_FILE=\"\"\n    Register --test-no AUTH-9409 --os OpenBSD --weight L --network NO --category security --description \"Checking /etc/doas.conf file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: checking presence /etc/doas.conf\"\n        if [ -f /etc/doas.conf ]; then\n        DOAS_FILE=/etc/doas.conf\n            FOUND=1\n            LogText \"Result: file /etc/doas.conf found\"\n        else\n            LogText \"Result: file /etc/doas.conf not found\"\n        fi\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: /etc/doas.conf file found\"\n            Display --indent 2 --text \"- doas file\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: doas file NOT found\"\n            Display --indent 2 --text \"- doas file\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : AUTH-9410\n    # Description : Check for doas file permissions\n    if [ -n \"${DOAS_FILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no AUTH-9410 --os OpenBSD --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check /etc/doas.conf file permissions\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking /etc/doas.conf permissions\"\n        FIND=$(ls -l ${DOAS_FILE} | ${CUTBINARY} -c 2-10)\n        LogText \"Result: Found /etc/doas.conf file permissions: ${FIND}\"\n        case \"${FIND}\" in\n            r[w-]-[r-][w-]---- )\n                LogText \"Result: file /etc/doas.conf has correct permissions\"\n                Display --indent 4 --text \"- Check doas file permissions\" --result \"${STATUS_OK}\" --color GREEN\n                ;;\n            * )\n                LogText \"Result: file has possibly unsafe file permissions\"\n                Display --indent 4 --text \"- Check doas file permissions\" --result \"${STATUS_WARNING}\" --color RED\n                ;;\n        esac\n    fi\n#\n#################################################################################\n#\n\nReport \"auth_failed_logins_logged=${AUTH_FAILED_LOGINS_LOGGED}\"\nReport \"ldap_auth_enabled=${LDAP_AUTH_ENABLED}\"\nReport \"ldap_pam_enabled=${LDAP_PAM_ENABLED}\"\nif [ -n \"${LDAP_CLIENT_CONFIG_FILE}\" ]; then Report \"ldap_config_file=${LDAP_CLIENT_CONFIG_FILE}\"; fi\nReport \"password_min_days=${PASSWORD_MINIMUM_DAYS}\"\nReport \"password_max_days=${PASSWORD_MAXIMUM_DAYS}\"\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_banners",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Banners and identification\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_BANNERS_AND_IDENTIFICATION}\"\n#\n#################################################################################\n#\n    BANNER_FILES=\"${ROOTDIR}etc/issue ${ROOTDIR}etc/issue.net ${ROOTDIR}etc/motd\"\n    LEGAL_BANNER_STRINGS=\"audit access authori condition connect consent continu criminal enforce evidence forbidden intrusion law legal legislat log monitor owner penal policy policies privacy private prohibited prosecute record report restricted secure subject system terms warning\"\n#\n#################################################################################\n#\n    # Test        : BANN-7113\n    # Description : Check FreeBSD COPYRIGHT banner file\n    Register --test-no BANN-7113 --os FreeBSD --weight L --network NO --category security --description \"Check COPYRIGHT banner file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Testing existence ${ROOTDIR}COPYRIGHT or ${ROOTDIR}etc/COPYRIGHT\"\n        if [ -f ${ROOTDIR}COPYRIGHT ]; then\n            Display --indent 2 --text \"- ${ROOTDIR}COPYRIGHT\" --result \"${STATUS_FOUND}\" --color GREEN\n            if [ -s ${ROOTDIR}COPYRIGHT ]; then\n                LogText \"Result: ${ROOTDIR}COPYRIGHT available and contains text\"\n            else\n                LogText \"Result: ${ROOTDIR}COPYRIGHT available, but empty\"\n            fi\n        else\n            Display --indent 2 --text \"- ${ROOTDIR}COPYRIGHT\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: ${ROOTDIR}COPYRIGHT not found\"\n        fi\n\n        if [ -f ${ROOTDIR}etc/COPYRIGHT ]; then\n            Display --indent 2 --text \"- ${ROOTDIR}etc/COPYRIGHT\" --result \"${STATUS_FOUND}\" --color GREEN\n            if [ -s ${ROOTDIR}etc/COPYRIGHT ]; then\n                LogText \"Result: ${ROOTDIR}etc/COPYRIGHT available and contains text\"\n            else\n                LogText \"Result: ${ROOTDIR}etc/COPYRIGHT available, but empty\"\n            fi\n        else\n            Display --indent 2 --text \"- ${ROOTDIR}etc/COPYRIGHT\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: ${ROOTDIR}etc/COPYRIGHT not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BANN-7124\n    # Description : Check issue banner file\n    Register --test-no BANN-7124 --weight L --network NO --category security --description \"Check issue banner file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking file ${ROOTDIR}etc/issue\"\n        if [ -f ${ROOTDIR}etc/issue ]; then\n            # Check for symlink\n            if [ -L ${ROOTDIR}etc/issue ]; then\n                LogText \"Result: file ${ROOTDIR}etc/issue exists (symlink)\"\n                Display --indent 2 --text \"- ${ROOTDIR}etc/issue\" --result SYMLINK --color GREEN\n            else\n                Display --indent 2 --text \"- ${ROOTDIR}etc/issue\" --result \"${STATUS_FOUND}\" --color GREEN\n            fi\n        else\n            LogText \"Result: file ${ROOTDIR}etc/issue does not exist\"\n            Display --indent 2 --text \"- ${ROOTDIR}etc/issue\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BANN-7126\n    # Description : Check issue file to see if it contains some form of message\n    #               to discourage unauthorized users to leave the system alone\n    if [ -f ${ROOTDIR}etc/issue ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no BANN-7126 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check issue banner file contents\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        FILE=\"${ROOTDIR}etc/issue\"\n        LogText \"Test: Checking file ${FILE} contents for legal key words\"\n        for ITEM in ${LEGAL_BANNER_STRINGS}; do\n            FIND=$(${GREPBINARY} -i \"${ITEM}\" ${FILE})\n            if HasData \"${FIND}\"; then\n                LogText \"Result: found string '${ITEM}'\"\n                COUNT=$((COUNT + 1))\n            fi\n        done\n        # Check if we have 5 or more key words\n        if [ ${COUNT} -gt 4 ]; then\n            LogText \"Result: Found ${COUNT} key words (5 or more suggested), to warn unauthorized users\"\n            Display --indent 4 --text \"- ${FILE} contents\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        else\n            LogText \"Result: Found only ${COUNT} key words (5 or more suggested), to warn unauthorized users and could be increased\"\n            Display --indent 4 --text \"- ${FILE} contents\" --result \"${STATUS_WEAK}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Add a legal banner to ${FILE}, to warn unauthorized users\"\n            AddHP 0 1\n            Report \"weak_banner_file[]=${FILE}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BANN-7128\n    # Description : Check issue.net banner file\n    Register --test-no BANN-7128 --weight L --network NO --category security --description \"Check issue.net banner file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking file ${ROOTDIR}etc/issue.net\"\n        if [ -f ${ROOTDIR}etc/issue.net ]; then\n            # Check for symlink\n            if [ -L ${ROOTDIR}etc/issue.net ]; then\n                LogText \"Result: file ${ROOTDIR}etc/issue.net exists (symlink)\"\n                Display --indent 2 --text \"- ${ROOTDIR}etc/issue.net\" --result SYMLINK --color GREEN\n            else\n                LogText \"Result: file ${ROOTDIR}etc/issue.net exists\"\n                Display --indent 2 --text \"- ${ROOTDIR}etc/issue.net\" --result \"${STATUS_FOUND}\" --color GREEN\n            fi\n        else\n            LogText \"Result: file ${ROOTDIR}etc/issue.net does not exist\"\n            Display --indent 2 --text \"- ${ROOTDIR}etc/issue.net\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BANN-7130\n    # Description : Check issue.net file to see if it contains some form of message\n    #               to discourage unauthorized users to leave the system alone\n    if [ -f ${ROOTDIR}etc/issue.net ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no BANN-7130 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check issue.net banner file contents\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: Checking file ${ROOTDIR}etc/issue.net contents for legal key words\"\n        for ITEM in ${LEGAL_BANNER_STRINGS}; do\n            FIND=$(${GREPBINARY} -i \"${ITEM}\" ${ROOTDIR}etc/issue.net)\n            if HasData \"${FIND}\"; then\n                LogText \"Result: found string '${ITEM}'\"\n                COUNT=$((COUNT + 1))\n            fi\n        done\n        # Check if we have 5 or more key words\n        if [ ${COUNT} -gt 4 ]; then\n            LogText \"Result: Found ${COUNT} key words, to warn unauthorized users\"\n            Display --indent 4 --text \"- ${ROOTDIR}etc/issue.net contents\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        else\n            LogText \"Result: Found only ${COUNT} key words, to warn unauthorized users and could be increased\"\n            Display --indent 4 --text \"- ${ROOTDIR}etc/issue.net contents\" --result \"${STATUS_WEAK}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Add legal banner to /etc/issue.net, to warn unauthorized users\"\n            AddHP 0 1\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_boot_services",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Category: Boot and services\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_BOOT_AND_SERVICES}\"\n#\n#################################################################################\n#\n    BOOT_LOADER=\"unknown\"\n    BOOT_LOADER_FOUND=0\n    BOOT_LOADER_SEARCHED=0\n    GRUB_VERSION=0\n    if [ -z \"${SERVICE_MANAGER}\" ]; then\n        SERVICE_MANAGER=\"unknown\"\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5102\n    # Description : Check for AIX boot device\n    # Notes       : The AIX bootstrap is called as software ROS. Bootstrap contains IPL (Initial Program loader)\n    #               TODO - binary detection of bootinfo and replace with variable\n    Register --test-no BOOT-5102 --os AIX --weight L --network NO --root-only YES --category security --description \"Check for AIX boot device\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        LogText \"Test: Query bootinfo for AIX boot device\"\n        if [ -x /usr/sbin/bootinfo ]; then\n            FIND=$(/usr/sbin/bootinfo -b)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found boot device ${FIND}\"\n                Display --indent 2 --text \"- Checking boot device (bootinfo)\" --result \"${STATUS_FOUND}\" --color GREEN\n                BOOT_LOADER=\"ROS\"\n                BOOT_LOADER_FOUND=1\n            else\n                LogText \"Result: no data received from bootinfo, most likely boot device not found\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5104\n    # Description : Determine service manager\n    # Notes       :\n    # initscripts     - Used by Arch before\n    # runit           - Used by Artix, Devuan, Dragora and Void\n    # systemd         - Common option with more Linux distros implementing it\n    # upstart         - Used by Debian/Ubuntu\n    Register --test-no BOOT-5104 --weight L --network NO --category security --description \"Determine service manager\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        case ${OS} in\n            \"Linux\")\n                if [ -f /proc/1/cmdline ]; then\n                    OUTPUT=$(${AWKBINARY} '/(^\\/|init|runit)/ { print $1 }' /proc/1/cmdline | ${TRBINARY} '\\0' ' ' | ${SEDBINARY} 's/ $//')\n                    LogText \"Result: cmdline found = ${OUTPUT}\"\n                    FILENAME=$(echo \"${OUTPUT}\" | ${AWKBINARY} '{print $1}')\n                    LogText \"Result: file on disk = ${FILENAME}\"\n                    ISFILE=$(echo ${FILENAME} | ${GREPBINARY} \"^/\")\n                    if [ -n \"${ISFILE}\" ]; then\n                        if [ -L ${ISFILE} ]; then\n                            ShowSymlinkPath ${ISFILE}\n                            FILENAME=\"${SYMLINK}\"\n                        elif [ -f ${ISFILE} ]; then\n                            FILENAME=\"${ISFILE}\"\n                        else\n                            LogText \"Result: cmdline of PID 1 is not a file\"\n                        fi\n                    fi\n                    if [ -n \"${FILENAME}\" ]; then\n                        SHORTNAME=$(echo ${FILENAME} | ${AWKBINARY} -F/ '{ print $NF }')\n                        LogText \"Found: ${SHORTNAME}\"\n                        if [ \"${SERVICE_MANAGER}\" = \"unknown\" ]; then\n                            case ${SHORTNAME} in\n                                busybox)\n                                    SERVICE_MANAGER=\"busybox\"\n                                ;;\n\n                                \"init\" | \"initsplash\")\n                                    if [ -d ${ROOTDIR}etc/rc.d ]; then\n                                        SERVICE_MANAGER=\"bsdrc.d\"\n                                    else\n                                        SERVICE_MANAGER=\"SysV Init\"\n                                    fi\n                                ;;\n                                systemd)\n                                    SERVICE_MANAGER=\"systemd\"\n                                ;;\n                                upstart)\n                                    SERVICE_MANAGER=\"upstart\"\n                                ;;\n                                runit)\n                                    SERVICE_MANAGER=\"runit\"\n                                ;;\n\t\t\t\topenrc-init)\n                                    SERVICE_MANAGER=\"openrc\"\n                                ;;\n                                *)\n                                    CONTAINS_SYSTEMD=$(echo ${SHORTNAME} | ${GREPBINARY} \"systemd\")\n                                    if [ -n \"${CONTAINS_SYSTEMD}\" ]; then\n                                        SERVICE_MANAGER=\"systemd\"\n                                    else\n                                        LogText \"Found ${SHORTNAME}. Unclear what service manager this is\"\n                                        ReportException \"${TEST_NO}:001\" \"Unknown service manager\"\n                                    fi\n                                ;;\n                            esac\n                        fi\n                    else\n                        LogText \"Result: /proc/1/cmdline seems to be empty\"\n                        ReportException \"${TEST_NO}:002\" \"No data found in /proc/1/cmdline\"\n                    fi\n                fi\n                # Continue testing if we didn't find it yet\n                if [ \"${SERVICE_MANAGER}\" = \"unknown\" ]; then\n                    if [ -f /usr/bin/init-openrc ]; then SERVICE_MANAGER=\"openrc\"; fi\n                fi\n            ;;\n            \"DragonFly\" | \"NetBSD\" | \"FreeBSD\" | \"OpenBSD\")\n                if [ -x /sbin/init -a -d ${ROOTDIR}etc/rc.d -a -f ${ROOTDIR}etc/rc ]; then\n                    SERVICE_MANAGER=\"bsdrc\"\n                fi\n            ;;\n            \"macOS\")\n                if [ -x ${ROOTDIR}sbin/launchd ]; then\n                    SERVICE_MANAGER=\"launchd\"\n                fi\n            ;;\n            \"Solaris\")\n                if [ -x \"${ROOTDIR}usr/bin/svcs\" ]; then\n                    SERVICE_MANAGER=\"SMF (svcs)\"\n                elif [ -d \"${ROOTDIR}etc/init.d\" ]; then\n                    SERVICE_MANAGER=\"SysV Init\"\n                fi\n            ;;\n            *)\n                LogText \"Result: unknown service manager\"\n            ;;\n        esac\n        LogText \"Result: service manager found = ${SERVICE_MANAGER}\"\n        if [ \"${SERVICE_MANAGER}\" = \"\" -o \"${SERVICE_MANAGER}\" = \"unknown\" ]; then\n            Display --indent 2 --text \"- Service Manager\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        else\n            Display --indent 2 --text \"- Service Manager\" --result \"${SERVICE_MANAGER}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5106\n    # Description : Check if boot.efi is found on macOS/macOS\n    Register --test-no BOOT-5106 --os \"macOS\" --weight L --network NO --root-only YES --category security --description \"Check EFI boot file on Mac OS X/macOS\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        FileExists ${ROOTDIR}System/Library/CoreServices/boot.efi\n        if [ ${FILE_FOUND} -eq 1 ]; then\n            LogText \"Result: found macOS/Mac OS X boot.efi file\"\n            BOOT_LOADER=\"macOS-boot-EFI\"\n            BOOT_LOADER_FOUND=1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5108\n    # Description : Check for Syslinux\n    Register --test-no BOOT-5108 --os \"Linux\" --weight L --network NO --root-only YES --category security --description \"Check Syslinux as bootloader\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        FileExists ${ROOTDIR}boot/syslinux/syslinux.cfg\n        if [ ${FILE_FOUND} -eq 1 ]; then\n            LogText \"Result: found Syslinux\"\n            BOOT_LOADER=\"Syslinux\"\n            BOOT_LOADER_FOUND=1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5109\n    # Description : Check for rEFInd\n    Register --test-no BOOT-5109 --os \"Linux\" --weight L --network NO --root-only YES --category security --description \"Check rEFInd as bootloader\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        FileExists ${ROOTDIR}boot/refind_linux.conf\n        if [ ${FILE_FOUND} -eq 1 ]; then\n            LogText \"Result: found rEFInd\"\n            BOOT_LOADER=\"rEFInd\"\n            BOOT_LOADER_FOUND=1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5116\n    # Description : Check if system is booted in UEFI mode\n    Register --test-no BOOT-5116 --weight L --network NO --root-only YES --category security --description \"Check if system is booted in UEFI mode\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        UEFI_TESTS_PERFORMED=0\n        case ${OS} in\n            Linux)\n                UEFI_TESTS_PERFORMED=1\n                # Check if UEFI is available in this boot\n                LogText \"Test: checking if UEFI is used\"\n                if [ -d ${ROOTDIR}sys/firmware/efi ]; then\n                    LogText \"Result: system booted in UEFI mode\"\n                    UEFI_BOOTED=1\n                else\n                    LogText \"Result: UEFI not used, can't find /sys/firmware/efi directory\"\n                fi\n\n                # Test if Secure Boot is enabled\n                LogText \"Test: determine if Secure Boot is used\"\n                if [ -d ${ROOTDIR}sys/firmware/efi/efivars ]; then\n                    FIND=$(${LSBINARY} ${ROOTDIR}sys/firmware/efi/efivars/SecureBoot-* 2> /dev/null)\n                    if [ -n \"${FIND}\" ]; then\n                        for FILE in ${FIND}; do\n                            LogText \"Test: checking file ${FILE}\"\n                            # TODO: add detection for od\n                            J=$(od -An -t u1 ${FILE} | ${AWKBINARY} '{ print $5 }')\n                            if [ \"${J}\" = \"1\" ]; then\n                                LogText \"Result: found SecureBoot file with enabled status\"\n                                UEFI_BOOTED_SECURE=1\n                            else\n                                LogText \"Result: system not booted with Secure Boot (status 0 in file ${FILE})\"\n                            fi\n                        done\n                    fi\n                else\n                    LogText \"Result: system not booted with Secure Boot (no SecureBoot file found)\"\n                fi\n            ;;\n            #macOS)\n            # TODO: macOS ioreg -l -p IODeviceTree | ${GREPBINARY} firmware-abi\n            #;;\n            *)\n                LogText \"Result: no test implemented yet to test for UEFI on this platform\"\n            ;;\n        esac\n        if [ ${UEFI_BOOTED} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking UEFI boot\" --result \"${STATUS_ENABLED}\" --color GREEN\n            if [ ${UEFI_BOOTED_SECURE} -eq 1 ]; then\n                Display --indent 2 --text \"- Checking Secure Boot\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                Display --indent 2 --text \"- Checking Secure Boot\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            fi\n        else\n            if [ ${UEFI_TESTS_PERFORMED} -eq 1 ]; then\n                Display --indent 2 --text \"- Checking UEFI boot\" --result \"${STATUS_DISABLED}\" --color WHITE\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5117\n    # Description : Check for systemd-boot boot loader\n    if [ ! \"${BOOTCTLBINARY}\" = \"\" -a ${HAS_SYSTEMD} -eq 1 -a ${UEFI_BOOTED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no BOOT-5117 --preqs-met ${PREQS_MET} --os \"Linux\" --weight L --network NO --category security --description \"Check for systemd-boot bootloader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        CURRENT_BOOT_LOADER=$(${BOOTCTLBINARY} status --no-pager 2>/dev/null | ${AWKBINARY} '/Current Boot Loader/{ getline; print $2 }')\n        if [ \"${CURRENT_BOOT_LOADER}\" = \"systemd-boot\" ]; then\n\t    Display --indent 2 --text \"- Checking systemd-boot presence\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: found systemd-boot\"\n            BOOT_LOADER=\"systemd-boot\"\n            BOOT_LOADER_FOUND=1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5121\n    # Description : Check for GRUB boot loader\n    Register --test-no BOOT-5121 --weight L --network NO --category security --description \"Check for GRUB boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        FOUND=0\n        LogText \"Test: Checking for presence GRUB conf file (/boot/grub/grub.conf or /boot/grub/menu.lst)\"\n        if [ -f /boot/grub/grub.conf -o -f /boot/grub/menu.lst ]; then\n            FOUND=1\n            BOOT_LOADER=\"GRUB\"\n            BOOT_LOADER_FOUND=1\n            GRUB_VERSION=1\n            Display --indent 2 --text \"- Checking presence GRUB\" --result \"${STATUS_OK}\" --color GREEN\n            if [ -f /boot/grub/grub.conf ]; then GRUBCONFFILE=\"/boot/grub/grub.conf\"; else GRUBCONFFILE=\"/boot/grub/menu.lst\"; fi\n        fi\n\n        # GRUB2 configuration file\n        if [ -f /boot/grub/grub.cfg -o -f /boot/grub2/grub.cfg ]; then\n            FOUND=1\n            BOOT_LOADER=\"GRUB2\"\n            BOOT_LOADER_FOUND=1\n            GRUB_VERSION=2\n            Display --indent 2 --text \"- Checking presence GRUB2\" --result \"${STATUS_FOUND}\" --color GREEN\n            if [ -f /boot/grub/grub.cfg ]; then\n                GRUBCONFFILE=\"/boot/grub/grub.cfg\"\n            elif [ -f /boot/grub2/grub.cfg ]; then\n                GRUBCONFFILE=\"/boot/grub2/grub.cfg\"\n            fi\n            LogText \"Result: found GRUB2 configuration file (${GRUBCONFFILE})\"\n        fi\n\n        # Some OSes like Gentoo do not have /boot mounted by default\n        # TODO: root directory and rewrite ls statement\n        if [ -d /boot ]; then\n            if [ \"$(ls /boot/* 2> /dev/null)\" = \"\" -a -n \"${GRUB2INSTALLBINARY}\" ]; then\n                BOOT_LOADER_FOUND=1\n                LogText \"Result: found empty /boot, however with GRUB2 binary installed. Best guess is that GRUB2 is actually installed, but /boot not mounted\"\n                Display --indent 2 --text \"- Checking presence GRUB2\" --result \"POSSIBLE MATCH\" --color YELLOW\n                ReportManual \"${TEST_NO}:01\"\n            fi\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: no GRUB configuration file found.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5122\n    # Description : Check for GRUB boot loader configuration\n    if [ -n \"${GRUBCONFFILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no BOOT-5122 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for GRUB boot password\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n\n        if [ -d \"${ROOTDIR}etc/grub.d\" ]; then\n            CONF_FILES=$(${FINDBINARY} -L \"${ROOTDIR}etc/grub.d\" -type f -name \"[0-9][0-9]*\" -print0 | ${TRBINARY} '\\0' ' ' | ${TRBINARY} -d '[:cntrl:]')\n            CONF_FILES=\"${GRUBCONFFILE} ${ROOTDIR}boot/grub/custom.cfg ${CONF_FILES}\"\n        else\n            CONF_FILES=\"${GRUBCONFFILE} ${ROOTDIR}boot/grub/custom.cfg\"\n        fi\n\n        for FILE in ${CONF_FILES}; do\n            if [ -f \"${FILE}\" ]; then\n                LogText \"Found file ${FILE}, proceeding with tests.\"\n                if FileIsReadable \"${FILE}\"; then\n                    FIND=$(${GREPBINARY} 'password --md5' ${FILE} | ${GREPBINARY} -v '^#')\n                    FIND2=$(${GREPBINARY} 'password --encrypted' ${FILE} | ${GREPBINARY} -v '^#')\n                    FIND3=$(${GREPBINARY} 'set superusers' ${FILE} | ${GREPBINARY} -v '^#')\n                    FIND4=$(${GREPBINARY} 'password_pbkdf2' ${FILE} | ${GREPBINARY} -v '^#')\n                    FIND5=$(${GREPBINARY} 'grub.pbkdf2' ${FILE} | ${GREPBINARY} -v '^#')\n                    # GRUB1: Password should be set (MD5 or SHA1)\n                    if [ -n \"${FIND}\" -o -n \"${FIND2}\" ]; then\n                        FOUND=1\n                    # GRUB2: Superusers AND password should be defined\n                    elif [ -n \"${FIND3}\" ]; then\n                        if [ -n \"${FIND4}\" -o -n \"${FIND5}\" ]; then FOUND=1; fi\n                    else\n                        LogText \"Result: did not find hashed password line in this file\"\n                    fi\n                else\n                    LogText \"Result: Can not read '${FILE}' (no permission?)\"\n                fi\n            else\n                LogText \"Result: File '${FILE}' does not exist\"\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n                Display --indent 4 --text \"- Checking for password protection\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: GRUB has password protection.\"\n                AddHP 4 4\n        else\n                Display --indent 4 --text \"- Checking for password protection\" --result \"${STATUS_NONE}\" --color RED\n                LogText \"Result: Didn't find hashed password line in GRUB configuration\"\n                ReportSuggestion \"${TEST_NO}\" \"Set a password on GRUB boot loader to prevent altering boot configuration (e.g. boot in single user mode without password)\"\n                AddHP 0 2\n        fi\n        unset CONF_FILES FILE FIND FIND2 FIND3 FIND4 FIND5 FOUND\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5124\n    # Description : Check for FreeBSD boot loader\n    Register --test-no BOOT-5124 --os FreeBSD --weight L --network NO --category security --description \"Check for FreeBSD boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        if [ -f ${ROOTDIR}boot/boot1 -a -f ${ROOTDIR}boot/boot2 -a -f ${ROOTDIR}boot/loader ]; then\n            LogText \"Result: found boot1, boot2 and loader files in ${ROOTDIR}boot\"\n            Display --indent 2 --text \"- Checking presence FreeBSD loader\" --result \"${STATUS_FOUND}\" --color GREEN\n            BOOT_LOADER=\"FreeBSD\"\n            BOOT_LOADER_FOUND=1\n        else\n            LogText \"Result: Not all expected files found in ${ROOTDIR}boot\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5261\n    # Description : Check for DragonFly boot loader\n    Register --test-no BOOT-5261 --os DragonFly --weight L --network NO --category security --description \"Check for DragonFly boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        if [ -f ${ROOTDIR}boot/boot1 -a -f ${ROOTDIR}boot/boot2 -a -f ${ROOTDIR}boot/loader ]; then\n            LogText \"Result: found boot1, boot2 and loader files in ${ROOTDIR}boot\"\n            Display --indent 2 --text \"- Checking presence DragonFly loader\" --result \"${STATUS_FOUND}\" --color GREEN\n            BOOT_LOADER=\"DragonFly\"\n            BOOT_LOADER_FOUND=1\n        else\n            LogText \"Result: Not all expected files found in ${ROOTDIR}boot\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5126\n    # Description : Check for NetBSD boot loader\n    Register --test-no BOOT-5126 --os NetBSD --weight L --network NO --category security --description \"Check for NetBSD boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        if [ -f ${ROOTDIR}boot.${HARDWARE} -o -f ${ROOTDIR}boot -o -f ${ROOTDIR}ofwboot ]; then\n            LogText \"Result: found NetBSD secondary bootstrap\"\n            Display --indent 2 --text \"- Checking presence NetBSD loader\" --result \"${STATUS_FOUND}\" --color GREEN\n            BOOT_LOADER=\"NetBSD\"\n            BOOT_LOADER_FOUND=1\n        else\n            LogText \"Result: NetBSD secondary bootstrap not found\"\n            ReportException \"${TEST_NO}:1\" \"No boot loader found on NetBSD\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5139\n    # Description : Check for LILO boot loader\n    # Notes       : password= or password =\n    Register --test-no BOOT-5139 --weight L --network NO --category security --description \"Check for LILO boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        LILOCONFFILE=\"${ROOTDIR}etc/lilo.conf\"\n        LogText \"Test: checking for presence LILO configuration file\"\n        if [ -f ${LILOCONFFILE} ]; then\n            FileIsReadable ${LILOCONFFILE}\n            if [ ${CANREAD} -eq 1 ]; then\n                BOOT_LOADER=\"LILO\"\n                BOOT_LOADER_FOUND=1\n                Display --indent 2 --text \"- Checking presence LILO\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Checking password option LILO\"\n                FIND=$(${GREPBINARY} -E 'password[[:space:]]?=' ${LILOCONFFILE} | ${GREPBINARY} -v \"^#\")\n                if [ -z \"${FIND}\" ]; then\n                    if [ \"${MACHINE_ROLE}\" = \"server\" -o \"${MACHINE_ROLE}\" = \"workstation\" ]; then\n                        Display --indent 4 --text \"- Password option presence \" --result \"${STATUS_WARNING}\" --color RED\n                        LogText \"Result: no password set for LILO. Bootloader is unprotected to dropping to single user mode or unauthorized access to devices/data.\"\n                        ReportSuggestion \"${TEST_NO}\" \"Add a password to LILO, by adding a line to the lilo.conf file, above the first line saying 'image=<name>': password=<password>\"\n                        ReportWarning \"${TEST_NO}\" \"No password set on LILO bootloader\"\n                        AddHP 0 2\n                    elif [ \"${MACHINE_ROLE}\" = \"personal\" ]; then\n                        Display --indent 4 --text \"- Password option presence \" --result \"${STATUS_WARNING}\" --color yellow\n                        LogText \"Result: no password set for LILO. Bootloader is unprotected to dropping to single user mode or unauthorized access to devices/data.\"\n                        ReportSuggestion \"${TEST_NO}\" \"No password set on LILO bootloader. Add a password to LILO, by adding a line to the lilo.conf file, above the first line saying 'image=<name>': password=<password>\"\n                        AddHP 1 2\n                    else\n                        LogText \"Result: no password set for LILO, with unknown machine role\"\n                    fi\n                else\n                    Display --indent 4 --text \"- Password option presence \" --result \"${STATUS_OK}\" --color GREEN\n                    LogText \"Result: LILO password option set\"\n                    AddHP 4 4\n                fi\n            else\n                LogText \"Result: can not read ${LILOCONFFILE} (no permission)\"\n            fi\n        else\n            LogText \"Result: LILO configuration file not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5140\n    # Description : Check for ELILO boot loader\n    Register --test-no BOOT-5140 --os \"Linux\" --weight L --network NO --root-only YES --category security --description \"Check for ELILO boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        CONF_FILES=\"${ROOTDIR}etc/elilo.conf ${ROOTDIR}boot/efi/EFI/${LINUX_VERSION}/elilo.conf\"\n        for FILE in ${CONF_FILES}; do\n            FileExists ${FILE}\n            if [ ${FILE_FOUND} -eq 1 ]; then\n                Display --indent 2 --text \"- Checking boot loader ELILO\" --result \"${STATUS_FOUND}\" --color GREEN\n                LogText \"Result: found ELILO boot loader\"\n                BOOT_LOADER=\"ELILO\"\n                BOOT_LOADER_FOUND=1\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5142\n    # Description : Check for SILO boot loader\n    Register --test-no BOOT-5142 --weight L --network NO --category security --description \"Check SPARC Improved boot loader (SILO)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        if [ -f ${ROOTDIR}etc/silo.conf ]; then\n            LogText \"Result: Found SILO configuration file (/etc/silo.conf)\"\n            Display --indent 2 --text \"- Checking boot loader SILO\" --result \"${STATUS_FOUND}\" --color GREEN\n            BOOT_LOADER=\"SILO\"\n            BOOT_LOADER_FOUND=1\n        else\n            LogText \"Result: no SILO configuration file found.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5155\n    # Description : Check for YABOOT boot loader\n    Register --test-no BOOT-5155 --weight L --network NO --category security --description \"Check for YABOOT boot loader configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        LogText \"Test: Check for /etc/yaboot.conf\"\n        if [ -f /etc/yaboot.conf ]; then\n            LogText \"Result: Found YABOOT configuration file (/etc/yaboot.conf)\"\n            Display --indent 4 --text \"- Checking boot loader YABOOT\" --result \"${STATUS_FOUND}\" --color GREEN\n            BOOT_LOADER=\"YABOOT\"\n            BOOT_LOADER_FOUND=1\n        else\n            LogText \"Result: no YABOOT configuration file found.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5159\n    # Description : Check for OpenBSD boot loader\n    # More info   : Only OpenBSD\n    Register --test-no BOOT-5159 --os OpenBSD --weight L --network NO --category security --description \"Check for OpenBSD boot loader presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BOOT_LOADER_SEARCHED=1\n        FOUND=0\n        # Boot files\n        # /usr/mdec/biosboot: first stage bootstrap\n        # /boot             : second stage bootstrap\n        if [ -f ${ROOTDIR}usr/mdec/biosboot -a -f ${ROOTDIR}boot ]; then\n            FOUND=1\n        fi\n        # Configuration file\n        if [ -f ${ROOTDIR}etc/boot.conf ]; then\n            FOUND=1\n            Display --indent 2 --text \"- Checking ${ROOTDIR}etc/boot.conf\" --result \"${STATUS_FOUND}\" --color GREEN\n            FIND=$(${GREPBINARY} '^boot' ${ROOTDIR}etc/boot.conf)\n            if [ -z \"${FIND}\" ]; then\n                Display --indent 4 --text \"- Checking boot option\" --result \"${STATUS_WARNING}\" --color RED\n                #ReportSuggestion \"${TEST_NO}\" \"Add 'boot' to the ${ROOTDIR}etc/boot.conf file to disable the default 5 seconds waiting time, to disallow booting into single user mode.\"\n                ReportWarning \"${TEST_NO}\" \"System can be booted into single user mode without password\"\n            else\n                Display --indent 4 --text \"- Checking boot option\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Ok, boot option is enabled.\"\n            fi\n        else\n            Display --indent 2 --text \"- Checking ${ROOTDIR}etc/boot.conf\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            LogText \"Result: no ${ROOTDIR}etc/boot.conf found. When using the default boot loader, physical\"\n            LogText \"access to the server can be used to possibly enter single user mode.\"\n            ReportSuggestion \"${TEST_NO}\" \"Add 'boot' to the ${ROOTDIR}etc/boot.conf file to disable the default 5 seconds waiting time.\"\n        fi\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: found OpenBSD boot loader\"\n            BOOT_LOADER=\"OpenBSD\"\n            BOOT_LOADER_FOUND=1\n        fi\n    fi\n#\n#################################################################################\n#\n    if [ ${BOOT_LOADER_FOUND} -eq 0 -a ${BOOT_LOADER_SEARCHED} -eq 1 ]; then\n        # Your boot loader is not detected. Want to help supporting it, see the README\n        # ReportException \"BOOTLOADER\" \"No boot loader found\"\n        Display --indent 4 --text \"- Boot loader\" --result \"NONE FOUND\" --color YELLOW\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5165\n    # Description : Check for FreeBSD boot services\n    Register --test-no BOOT-5165 --os FreeBSD --weight L --network NO --category security --description \"Check for FreeBSD boot services\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if HasData \"${SERVICEBINARY}\"; then\n            # FreeBSD (Ask services(8) for enabled services)\n            LogText \"Searching for services at startup (service)\"\n            FIND=$(${SERVICEBINARY} -e | ${SEDBINARY} 's|^.*\\/||' | ${SORTBINARY})\n        else\n            # FreeBSD (Read /etc/rc.conf file for enabled services)\n            LogText \"Searching for services at startup (rc.conf)\"\n            FIND=$(${GREPBINARY} -E -v -i '^#|none' ${ROOTDIR}etc/rc.conf | ${GREPBINARY} -E -i '_enable.*(yes|on|1)' | ${SORTBINARY} | ${AWKBINARY} -F= '{ print $1 }' | ${SEDBINARY} 's/_enable//')\n        fi\n        COUNT=0\n        for ITEM in ${FIND}; do\n            LogText \"Found service (service/rc.conf): ${ITEM}\"\n            Report \"boottask[]=${ITEM}\"\n            COUNT=$((COUNT + 1))\n        done\n        Display --indent 2 --text \"- Checking services at startup (service/rc.conf)\" --result \"${STATUS_DONE}\" --color GREEN\n        Display --indent 6 --text \"Result: found ${COUNT} services/options set\"\n        LogText \"Found ${COUNT} services/options to run at startup\"\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5170\n    # Description : Check for Solaris boot daemons\n    Register --test-no BOOT-5170 --os Solaris --weight L --network NO --category security --description \"Check for Solaris boot daemons\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${SVCSBINARY}\" ]; then\n            LogText \"Result: Using svcs binary to check for daemons\"\n            LogText \"SysV style services may be incorrectly counted as running.\"\n\n            Report \"running_service_tool=svcs\"\n\n            # For the documentation of the states (field $1) see\n            # \"Managing System Services in Oracle Solaris 11.4\" pp. 24, available\n            # at https://docs.oracle.com/cd/E37838_01/pdf/E60998.pdf\n\n            FIND=$(\"${SVCSBINARY}\" -Ha | ${AWKBINARY} '{ if ($1 == \"online\" || $1 == \"legacy_run\") print $3 }')\n            COUNT=0\n            for ITEM in ${FIND}; do\n                LogText \"Found running daemon: ${ITEM}\"\n                Report \"running_service[]=${ITEM}\"\n                COUNT=$((COUNT + 1 ))\n            done\n            Display --indent 2 --text \"- Check running daemons (svcs)\" --result \"${STATUS_DONE}\" --color GREEN\n            Display --indent 8 --text \"Result: found ${COUNT} running daemons\"\n            LogText \"Result: Found ${COUNT} running daemons\"\n\n            LogText \"Searching for enabled daemons (svcs)\"\n            Report \"boot_service_tool=svcs\"\n\n            FIND=$(\"${SVCSBINARY}\" -Ha | ${AWKBINARY} '{ if ($1 != \"disabled\" && $1 != \"uninitialized\") print $3 }')\n            COUNT=0\n            for ITEM in ${FIND}; do\n                LogText \"Found enabled daemon at boot: ${ITEM}\"\n                Report \"boot_service[]=${ITEM}\"\n                COUNT=$((COUNT + 1 ))\n            done\n            LogText \"Note: Run svcs -a see all services\"\n            Display --indent 2 --text \"- Check enabled daemons at boot (svcs)\" --result \"${STATUS_DONE}\" --color GREEN\n            Display --indent 8 --text \"Result: found ${COUNT} enabled daemons at boot\"\n            LogText \"Result: Found ${COUNT} enabled daemons at boot\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5171\n    # Description : Check for services with errors on solaris\n#\n#################################################################################\n#\n    # Test        : BOOT-5177\n    # Description : Check for Linux boot services (systemd and chkconfig)\n    # Notes       : We skip using chkconfig if systemd is being used.\n    Register --test-no BOOT-5177 --os Linux --weight L --network NO --category security --description \"Check for Linux boot and running services\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        CHECKED=0\n        LogText \"Test: checking presence systemctl binary\"\n        # Determine if we have systemctl on board\n        if HasData \"${SYSTEMCTLBINARY}\"; then\n            LogText \"Result: systemctl binary found, trying that to discover information\"\n            # Running services\n            LogText \"Searching for running services (systemctl services only)\"\n            FIND=$(${SYSTEMCTLBINARY} --no-legend --full --type=service --state=running | ${AWKBINARY} -F.service '{ print $1 }')\n            COUNT=0\n            Report \"running_service_tool=systemctl\"\n            for ITEM in ${FIND}; do\n                LogText \"Found running service: ${ITEM}\"\n                Report \"running_service[]=${ITEM}\"\n                COUNT=$((COUNT + 1))\n            done\n            LogText \"Hint: Run systemctl --full --type=service to see all services\"\n            Display --indent 2 --text \"- Check running services (systemctl)\" --result \"${STATUS_DONE}\" --color GREEN\n            Display --indent 8 --text \"Result: found ${COUNT} running services\"\n            LogText \"Result: Found ${COUNT} running services\"\n\n            # Services at boot\n            LogText \"Searching for enabled services (systemctl services only)\"\n            FIND=$(${SYSTEMCTLBINARY} list-unit-files --no-legend --type=service --state=enabled | ${SORTBINARY} -u | ${AWKBINARY} -F.service '{ print $1 }')\n            COUNT=0\n            Report \"boot_service_tool=systemctl\"\n            for ITEM in ${FIND}; do\n                LogText \"Found enabled service at boot: ${ITEM}\"\n                Report \"boot_service[]=${ITEM}\"\n                COUNT=$((COUNT + 1))\n            done\n            LogText \"Hint: Run systemctl list-unit-files --type=service to see all services\"\n            Display --indent 2 --text \"- Check enabled services at boot (systemctl)\" --result \"${STATUS_DONE}\" --color GREEN\n            Display --indent 8 --text \"Result: found ${COUNT} enabled services\"\n            LogText \"Result: Found ${COUNT} enabled services\"\n\n        else\n\n            LogText \"Result: systemctl binary not found, checking chkconfig binary\"\n            if [ -n \"${CHKCONFIGBINARY}\" ]; then\n                LogText \"Result: chkconfig binary found, trying that to discover information\"\n                LogText \"Searching for services at startup (chkconfig, runlevel 3 and 5)\"\n                FIND=$(${CHKCONFIGBINARY} --list | ${GREPBINARY} -E '3:on|5:on' | ${AWKBINARY} '{ print $1 }')\n                COUNT=0\n                Report \"boot_service_tool=chkconfig\"\n                for ITEM in ${FIND}; do\n                    LogText \"Found service (at boot, runlevel 3 or 5): ${ITEM}\"\n                    Report \"boot_service[]=${ITEM}\"\n                    COUNT=$((COUNT + 1))\n                done\n                LogText \"Hint: Run chkconfig --list to see all services and disable unneeded services\"\n                Display --indent 2 --text \"- Check services at startup (chkconfig)\" --result \"${STATUS_DONE}\" --color GREEN\n                Display --indent 8 --text \"Result: found ${COUNT} services\"\n                LogText \"Result: Found ${COUNT} services at startup\"\n            else\n                LogText \"Result: both systemctl and chkconfig not found. Skipping this test\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5180\n    # Description : Check for Linux boot services (Debian style)\n    # Notes       : Debian 8+ shows runlevel 5\n    if [ \"${LINUX_VERSION}\" = \"Debian\" ] || [ \"${LINUX_VERSION}\" = \"Ubuntu\" ] ||\n           [ \"${LINUX_VERSION_LIKE}\" = \"Debian\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"Ubuntu\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    Register --test-no BOOT-5180 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for Linux boot services (Debian style)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Runlevel check\n        sRUNLEVEL=$(${RUNLEVELBINARY} | ${GREPBINARY} \"N [0-9]\" | ${AWKBINARY} '{ print $2} ')\n        LogText \"Result: found runlevel ${sRUNLEVEL}\"\n        if [ \"${sRUNLEVEL}\" = \"2\" ]; then\n            LogText \"Result: performing find in /etc/rc2.d as runlevel 2 is found\"\n            FIND=$(${FINDBINARY} ${ROOTDIR}etc/rc2.d -type l -print | ${CUTBINARY} -d '/' -f4 | ${SEDBINARY} \"s/S[0-9][0-9]//g\" | sort)\n            if [ -n \"${FIND}\" ]; then\n                COUNT=0\n                for SERVICE in ${FIND}; do\n                    LogText \"Found service (at boot, runlevel 2): ${SERVICE}\"\n                    COUNT=$((COUNT + 1))\n                done\n                Display --indent 2 --text \"- Check services at startup (rc2.d)\" --result \"${STATUS_DONE}\" --color WHITE\n                Display --indent 4 --text \"Result: found ${COUNT} services\"\n                LogText \"Result: found ${COUNT} services\"\n            fi\n        elif [ -z \"${sRUNLEVEL}\" ]; then\n            ReportSuggestion \"${TEST_NO}\" \"Determine runlevel and services at startup\"\n        else\n            LogText \"Result: skipping further actions\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5184\n    # Description : Check world writable startup scripts\n    Register --test-no BOOT-5184 --os \"Linux Solaris\" --weight L --network NO --category security --description \"Check permissions for boot files/scripts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        CHECKDIRS=\"${ROOTDIR}etc/init.d ${ROOTDIR}etc/rc.d ${ROOTDIR}etc/rcS.d\"\n\n        LogText \"Result: checking ${ROOTDIR}etc/init.d scripts for writable bit\"\n        for DIR in ${CHECKDIRS}; do\n            LogText \"Test: checking if directory ${DIR} exists\"\n            if [ -d ${DIR} ]; then\n                LogText \"Result: directory ${DIR} found\"\n                LogText \"Test: checking for available files in directory\"\n                FIND=$(${FINDBINARY} -L ${DIR} -type f -print | ${SORTBINARY})\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found files in directory, checking permissions now\"\n                    for FILE in ${FIND}; do\n                        LogText \"Test: checking permissions of file ${FILE}\"\n                        if IsWorldWritable ${FILE}; then\n                            FOUND=1\n                            LogText \"Result: warning, file ${FILE} is world writable\"\n                        else\n                            LogText \"Result: good, file ${FILE} not world writable\"\n                        fi\n                    done\n                else\n                    LogText \"Result: found no files in directory.\"\n                fi\n            else\n                LogText \"Result: directory ${DIR} not found. Skipping..\"\n            fi\n        done\n\n        # /etc/rc[0-6].d\n        for NO in 0 1 2 3 4 5 6; do\n            LogText \"Test: Checking ${ROOTDIR}etc/rc${NO}.d scripts for writable bit\"\n            if [ -d ${ROOTDIR}etc/rc${NO}.d ]; then\n                FIND=$(${FINDBINARY} -L ${ROOTDIR}etc/rc${NO}.d -type f -print | ${SORTBINARY})\n                for I in ${FIND}; do\n                    if IsWorldWritable ${I}; then\n                        FOUND=1\n                        LogText \"Result: warning, file ${I} is world writable\"\n                    else\n                        LogText \"Result: good, file ${I} not world writable\"\n                    fi\n                done\n            fi\n        done\n\n        # Other files\n        CHECKFILES=\"${ROOTDIR}etc/rc ${ROOTDIR}etc/rc.local ${ROOTDIR}etc/rc.d/rc.sysinit\"\n        for I in ${CHECKFILES}; do\n            if [ -f ${I} ]; then\n                ShowSymlinkPath \"${I}\"\n                if [ ${FOUNDPATH} -eq 1 ]; then\n                    CHECKFILE=\"${SYMLINK}\"\n                    LogText \"Result: found the path behind this symlink (${CHECKFILE} --> ${I})\"\n                else\n                    CHECKFILE=\"${I}\"\n                fi\n                LogText \"Test: Checking ${CHECKFILE} file for writable bit\"\n                if IsWorldWritable ${CHECKFILE}; then\n                    FOUND=1\n                    ReportWarning \"${TEST_NO}\" \"Found writable startup script ${CHECKFILE}\"\n                    LogText \"Result: warning, file ${CHECKFILE} is world writable\"\n                else\n                    LogText \"Result: good, file ${CHECKFILE} not world writable\"\n                fi\n            fi\n        done\n\n        # Check results\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Check startup files (permissions)\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Found world writable startup scripts\" \"-\" \"-\"\n            LogText \"Result: found one or more scripts which are possibly writable by other users\"\n            AddHP 0 3\n        else\n            Display --indent 2 --text \"- Check startup files (permissions)\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5202\n    # Description : Check uptime of system\n    Register --test-no BOOT-5202 --weight L --network NO --category security --description \"Check uptime of system\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        FIND=\"\"\n        UPTIME_IN_SECS=\"\"\n        case \"${OS}\" in\n            Linux)\n                # Idle time, not real uptime\n                if [ -f /proc/uptime ]; then\n                    UPTIME_IN_SECS=$(${CUTBINARY} -d ' ' -f1 /proc/uptime | ${CUTBINARY} -d '.' -f1)\n                else\n                    Display --indent 2 --text \"- Checking uptime\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n                    ReportException \"${TEST_NO}:1\" \"No uptime test available for this operating system (/proc/uptime missing)\"\n                fi\n            ;;\n\n            DragonFly | FreeBSD | macOS)\n                if [ -n \"${SYSCTLBINARY}\" ]; then\n                    TIME_BOOT=$(${SYSCTLBINARY} kern.boottime | ${AWKBINARY} '{ print $5 }' | ${SEDBINARY} -e 's/,//' | ${GREPBINARY} \"[0-9]\")\n                    TIME_NOW=$(date \"+%s\")\n                    LogText \"Boot time: ${TIME_BOOT}\"\n                    LogText \"Current time: ${TIME_NOW}\"\n                    if [ -n \"${TIME_BOOT}\" -a -n \"${TIME_NOW}\" ]; then\n                        UPTIME_IN_SECS=$((TIME_NOW - TIME_BOOT))\n                    else\n                        ReportException \"${TEST_NO}:5\" \"Most likely kern.boottime empty, unable to determine uptime\"\n                    fi\n                else\n                    Display --indent 2 --text \"- Checking uptime\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n                    ReportException \"${TEST_NO}:4\" \"No uptime test available for this operating system (sysctl missing)\"\n                fi\n            ;;\n\n            NetBSD | OpenBSD)\n                if [ -n \"${SYSCTLBINARY}\" ]; then\n                    TIME_BOOT=$(${SYSCTLBINARY} -n kern.boottime)\n                    TIME_NOW=$(date \"+%s\")\n                    LogText \"Boot time: ${TIME_BOOT}\"\n                    LogText \"Current time: ${TIME_NOW}\"\n                    if [ -n \"${TIME_BOOT}\" -a -n \"${TIME_NOW}\" ]; then\n                        UPTIME_IN_SECS=$((TIME_NOW - TIME_BOOT))\n                    else\n                        ReportException \"${TEST_NO}:5\" \"Most likely kern.boottime empty, unable to determine uptime\"\n                    fi\n                else\n                    Display --indent 2 --text \"- Checking uptime\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n                    ReportException \"${TEST_NO}:4\" \"No uptime test available for this operating system (sysctl missing)\"\n                fi\n            ;;\n\n            Solaris)\n                if [ -n \"${KSTATBINARY}\" ]; then\n                    UPTIME_IN_SECS=$(${KSTATBINARY} -p unix:0:system_misc:snaptime | ${GREPBINARY} \"^unix\" | ${AWKBINARY} '{print $2}' | ${CUTBINARY} -d \".\" -f1)\n                else\n                    Display --indent 2 --text \"- Checking uptime\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n                    ReportException \"${TEST_NO}:2\" \"No uptime test available for this operating system (kstat missing)\"\n                fi\n            ;;\n\n            *)\n                Display --indent 2 --text \"- Checking uptime\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n\n                # Want to help improving Lynis? Share your operating system and a way to determine the uptime (in seconds)\n                ReportException \"${TEST_NO}:3\" \"No uptime test available yet for this operating system\"\n            ;;\n        esac\n\n        if [ -n \"${UPTIME_IN_SECS}\" ]; then\n            UPTIME_IN_DAYS=$((UPTIME_IN_SECS / 60 / 60 / 24))\n            LogText \"Uptime (in seconds): ${UPTIME_IN_SECS}\"\n            LogText \"Uptime (in days): ${UPTIME_IN_DAYS}\"\n            Report \"uptime_in_seconds=${UPTIME_IN_SECS}\"\n            Report \"uptime_in_days=${UPTIME_IN_DAYS}\"\n        else\n            LogText \"Result: no uptime information available\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5260\n    # Description : Check single user mode for systemd\n    Register --test-no BOOT-5260 --os Linux --weight L --network NO --category security --description \"Check single user mode for systemd\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching /usr/lib/systemd/system/rescue.service\"\n        if [ -f ${ROOTDIR}usr/lib/systemd/system/rescue.service ]; then\n            LogText \"Result: file /usr/lib/systemd/system/rescue.service\"\n            LogText \"Test: checking presence sulogin for single user mode\"\n            FIND=$(${GREPBINARY} -E \"^ExecStart=.*sulogin\" ${ROOTDIR}usr/lib/systemd/system/rescue.service)\n            if [ -n \"${FIND}\" ]; then\n                FOUND=1\n                LogText \"Result: found sulogin, so single user is protected\"\n                AddHP 3 3\n            else\n                LogText \"Result: did not find sulogin in rescue.service\"\n                AddHP 1 3\n                Display --indent 2 --text \"- Checking sulogin in rescue.service\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Protect rescue.service by using sulogin\"\n            fi\n        else\n            LogText \"Result: file ${ROOTDIR}usr/lib/systemd/system/rescue.service does not exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5262\n    # Description : Check for OpenBSD boot daemons\n    Register --test-no BOOT-5262 --os OpenBSD --weight L --network NO --category security --description \"Check for OpenBSD boot daemons\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if HasData \"${RCCTLBINARY}\"; then\n            LogText \"Result: rcctl binary found, trying that to discover information\"\n            # OpenBSD (Ask rcctl(8) for running daemons)\n            LogText \"Searching for running daemons (rcctl)\"\n            FIND=$(${RCCTLBINARY} ls started)\n            COUNT=0\n            Report \"running_service_tool=rcctl\"\n            for ITEM in ${FIND}; do\n                LogText \"Found running daemon: ${ITEM}\"\n                Report \"running_service[]=${ITEM}\"\n                COUNT=$((COUNT + 1 ))\n            done\n            LogText \"Note: Run rcctl ls all | grep -E '^(pf|check_quotas|library_aslr)$' to see all daemons\"\n            Display --indent 2 --text \"- Check running daemons (rcctl)\" --result \"${STATUS_DONE}\" --color GREEN\n            Display --indent 8 --text \"Result: found ${COUNT} running daemons\"\n            LogText \"Result: Found ${COUNT} running daemons\"\n\n            # OpenBSD (Ask rcctl(8) for enabled daemons)\n            LogText \"Searching for enabled daemons (rcctl)\"\n            FIND=$(${RCCTLBINARY} ls on | ${GREPBINARY} -E -v '^(pf|check_quotas|library_aslr)$')\n            COUNT=0\n            Report \"boot_service_tool=rcctl\"\n            for ITEM in ${FIND}; do\n                LogText \"Found enabled daemon at boot: ${ITEM}\"\n                Report \"boot_service[]=${ITEM}\"\n                COUNT=$((COUNT + 1 ))\n            done\n            LogText \"Note: Run rcctl ls all | grep -E  '^(pf|check_quotas|library_aslr)$' to see all daemons\"\n            Display --indent 2 --text \"- Check enabled daemons at boot (rcctl)\" --result \"${STATUS_DONE}\" --color GREEN\n            Display --indent 8 --text \"Result: found ${COUNT} enabled daemons at boot\"\n            LogText \"Result: Found ${COUNT} enabled daemons at boot\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5263\n    # Description : Check OpenBSD world writable startup scripts\n    Register --test-no BOOT-5263 --os OpenBSD --weight L --network NO --category security --description \"Check permissions for boot files/scripts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        CHECKDIR=\"${ROOTDIR}etc/rc.d\"\n        LogText \"Result: checking ${ROOTDIR}etc/rc.d scripts for writable bit\"\n        LogText \"Test: checking if directory ${DIR} exists\"\n        if [ -d ${CHECKDIR} ]; then\n            LogText \"Result: directory ${DIR} found\"\n            LogText \"Test: checking for available files in directory\"\n            # OpenBSD uses symlinks to create another instance of daemons\n            FIND=$(${FINDBINARY} -L ${CHECKDIR} -type f -print | ${SORTBINARY})\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found files in directory, checking permissions now\"\n                for FILE in ${FIND}; do\n                    LogText \"Test: checking permissions of file ${FILE}\"\n                    ShowSymlinkPath \"${FILE}\"\n                    if [ ${FOUNDPATH} -eq 1 ]; then\n                        CHECKFILE=\"${SYMLINK}\"\n                        LogText \"Result: found the path behind this symlink (${CHECKFILE} --> ${FILE})\"\n                    else\n                        CHECKFILE=\"${FILE}\"\n                    fi\n                    if IsWorldWritable ${CHECKFILE}; then\n                        FOUND=1\n                        LogText \"Result: warning, file ${CHECKFILE} is world writable\"\n                    else\n                        LogText \"Result: good, file ${CHECKFILE} not world writable\"\n                    fi\n                done\n            else\n                LogText \"Result: found no files in directory.\"\n            fi\n        else\n            LogText \"Result: directory ${CHECKDIR} not found. Skipping..\"\n        fi\n\n        # Other files\n        CHECKFILES=\"${ROOTDIR}etc/rc ${ROOT}etc/rc.conf ${ROOT}etc/rc.conf.local ${ROOTDIR}etc/rc.local\"\n        for I in ${CHECKFILES}; do\n            if [ -f ${I} ]; then\n                ShowSymlinkPath \"${I}\"\n                if [ ${FOUNDPATH} -eq 1 ]; then\n                    CHECKFILE=\"${SYMLINK}\"\n                    LogText \"Result: found the path behind this symlink (${CHECKFILE} --> ${I})\"\n                else\n                    CHECKFILE=\"${I}\"\n                fi\n                LogText \"Test: Checking ${CHECKFILE} file for writable bit\"\n                if IsWorldWritable ${CHECKFILE}; then\n                    FOUND=1\n                    ReportWarning \"${TEST_NO}\" \"Found writable startup script ${CHECKFILE}\"\n                    LogText \"Result: warning, file ${CHECKFILE} is world writable\"\n                else\n                    LogText \"Result: good, file ${CHECKFILE} not world writable\"\n                fi\n            fi\n        done\n\n        # Check results\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Check startup files (permissions)\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Found world writable startup scripts\" \"-\" \"-\"\n            LogText \"Result: found one or more scripts which are possibly writable by other users\"\n            AddHP 0 3\n        else\n            Display --indent 2 --text \"- Check startup files (permissions)\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : BOOT-5264\n    # Description : Run systemd-analyze security\n    if [ -z \"${SYSTEMDANALYZEBINARY}\" ]; then SKIPREASON=\"systemd-analyze not available\"; PREQS_MET=\"NO\";\n    else\n        SYSTEMD_VERSION=$(\"${SYSTEMDANALYZEBINARY}\" --version | ${AWKBINARY} '/^systemd / {print $2}')\n        if [ \"${SYSTEMD_VERSION}\" -ge 240 ]; then PREQS_MET=\"YES\"; else SKIPREASON=\"systemd-analyze too old (v${SYSTEMD_VERSION}), need at least v240\"; PREQS_MET=\"NO\"; fi\n    fi\n    Register --test-no BOOT-5264 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --os Linux --weight L --network NO --category security --description \"Run systemd-analyze security\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Run systemd-analyze security\"\n        Display --indent 2 --text \"- Running 'systemd-analyze security'\"\n        Display --indent 6 --text \"Unit name (exposure value) and predicate\"\n        Display --indent 6 --text \"--------------------------------\"\n        ${SYSTEMDANALYZEBINARY} security | while read UNIT EXPOSURE PREDICATE HAPPY; do\n            if [ \"${UNIT}\" = \"UNIT\" ]; then\n                continue\n            fi\n            STATUS=\"UNKNOWN\"\n            COLOR=\"BLACK\"\n            case ${PREDICATE} in\n                PERFECT | SAFE | OK)\n                    STATUS=\"${STATUS_PROTECTED}\"\n                    COLOR=GREEN\n                ;;\n                MEDIUM)\n                    STATUS=\"${STATUS_MEDIUM}\"\n                    COLOR=WHITE\n                ;;\n                EXPOSED)\n                    STATUS=\"${STATUS_EXPOSED}\"\n                    COLOR=YELLOW\n                ;;\n                UNSAFE | DANGEROUS)\n                    STATUS=\"${STATUS_UNSAFE}\"\n                    COLOR=YELLOW\n                ;;\n            esac\n            Display --indent 4 --text \"- ${UNIT} (value=${EXPOSURE})\" --result \"${STATUS}\" --color \"${COLOR}\"\n            LogText \"Result: ${UNIT} has exposure value ${EXPOSURE} with predicate '${STATUS}'\"\n        done\n        ReportSuggestion \"${TEST_NO}\" \"Consider hardening system services\" \"Run '${SYSTEMDANALYZEBINARY} security SERVICE' for each service\"\n    fi\n#\n#################################################################################\n#\n\nReport \"boot_loader=${BOOT_LOADER}\"\nReport \"boot_uefi_booted=${UEFI_BOOTED}\"\nReport \"boot_uefi_booted_secure=${UEFI_BOOTED_SECURE}\"\nReport \"service_manager=${SERVICE_MANAGER}\"\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_containers",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Containers, Zones, Jails\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_CONTAINERS}\"\n#\n#################################################################################\n#\n    DOCKER_CONTAINERS_RUNNING=0\n    DOCKER_CONTAINERS_TOTAL=0\n    DOCKER_FILE_PERMISSIONS_WARNINGS=0\n    RUN_DOCKER_TESTS=0\n#\n#################################################################################\n#\n    # Test        : CONT-8004\n    # Description : Query running Solaris zones\n    if [ -x ${ROOTDIR}usr/sbin/zoneadm ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CONT-8004 --os Solaris --weight L --network NO --category security --description \"Query running Solaris zones\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: query zoneadm to list all running zones\"\n        FIND=$(${ROOTDIR}usr/sbin/zoneadm list -p | ${AWKBINARY} -F: '{ if ($2!=\"global\") print $0 }')\n        if [ -n \"${FIND}\" ]; then\n            COUNT=0\n            for ITEM in ${FIND}; do\n                COUNT=$((COUNT + 1))\n                ZONEID=$(echo ${ITEM} | ${CUTBINARY} -d ':' -f1)\n                ZONENAME=$(echo ${ITEM} | ${CUTBINARY} -d ':' -f2)\n                LogText \"Result: found zone ${ZONENAME} (running)\"\n                Report \"solaris_running_zone[]=${ZONENAME} [id:${ZONEID}]\"\n            done\n            LogText \"Result: total of ${COUNT} running zones\"\n            Display --indent 2 --text \"- Checking Solaris Zones\" --result \"FOUND ${COUNT} zones\" --color GREEN\n        else\n            LogText \"Result: no running zones found\"\n            Display --indent 2 --text \"- Checking Solaris Zones\" --result \"${STATUS_NONE}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Do you have Xen running? Help us testing this test and submit a pull request on GitHub\n\n    # Test        : CONT-1906 TODO\n    # Description : Query running Xen zones\n    #if [ -x /usr/bin/xm ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    #Register --test-no CONT-1906 --weight L --network NO --category security --description \"Query Xen guests\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n        # Show Xen guests\n        #FIND=$(xm list | ${AWKBINARY} '$1 != \"Name|Domain-0\" {print $1\",\"$2}')\n        #for I in ${FIND}; do\n            #XENGUESTNAME=$(echo ${I} | ${CUTBINARY} -d ':' -f1)\n            #XENGUESTID=$(echo ${I} | ${CUTBINARY} -d ':' -f2)\n            #LogText \"Result: found Xen guest ${XENGUESTNAME} (ID: ${XENGUESTID})\"\n        #done\n    #fi\n#\n#################################################################################\n#\n    # Test        : CONT-8102\n    # Description : Checking Docker daemon status and basic information for later tests\n    Register --test-no CONT-8102 --weight L --network NO --category security --description \"Checking Docker status and information\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning \"dockerd\"; then\n            LogText \"Result: found Docker daemon running\"\n            Report \"docker_daemon_running=1\"\n            DOCKER_DAEMON_RUNNING=1\n            RUN_DOCKER_TESTS=1\n            Display --indent 4 --text \"- Docker\"\n            Display --indent 6 --text \"- Docker daemon\" --result \"${STATUS_RUNNING}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CONT-8104\n    # Description : Checking Docker info for any warnings\n    # Notes       : Hardening points are awarded, as usually warnings are the result of missing controls to restrict boundaries like memory\n    if HasData \"${DOCKERBINARY}\"; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CONT-8104 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking Docker info for any warnings\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: Check for any warnings\"\n        FIND=$(${DOCKERBINARY} version 2>&1)\n        if [ $? -gt 0 ]; then\n            Display --indent 8 --text \"- Docker status\" --result \"${STATUS_ERROR}\" --color RED\n            LogText \"Result: disabling further Docker tests as docker version gave exit code other than zero (0)\"\n            RUN_DOCKER_TESTS=0\n        fi\n        FIND=$(${DOCKERBINARY} info 2>&1 | ${GREPBINARY} -E \"^WARNING:|^ERROR:\" | ${CUTBINARY} -d \" \" -f 2- | ${SEDBINARY} 's/ /:space:/g')\n        if [ ! \"${FIND}\" = \"\" ]; then\n            LogText \"Result: found warning(s) in output\"\n            for I in ${FIND}; do\n                J=$(echo ${I} | ${SEDBINARY} 's/:space:/ /g')\n                LogText \"Output: ${J}\"\n                COUNT=$((COUNT + 1))\n            done\n            Display --indent 8 --text \"- Docker info output (warnings)\" --result \"${COUNT}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Run 'docker info' to see warnings applicable to Docker daemon\"\n            AddHP 3 4\n        else\n            LogText \"Result: no warnings found from 'docker info' output\"\n            Display --indent 8 --text \"- Docker info output (warnings)\" --result \"${STATUS_NONE}\" --color GREEN\n            AddHP 1 1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CONT-8106\n    # Description : Checking Docker containers (basic stats)\n    # Notes       : Hardening points are awarded, if there aren't a lot of stopped containers\n    if [ -n \"${DOCKERBINARY}\" -a ${RUN_DOCKER_TESTS} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CONT-8106 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Gather basic stats from Docker\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 6 --text \"- Containers\"\n\n        # Check total of containers\n        LogText \"Test: checking total amount of Docker containers\"\n        DOCKER_CONTAINERS_TOTAL=$(${DOCKERBINARY} info 2> /dev/null | ${GREPBINARY} -E \"^[ \\t]?Containers: \" | ${AWKBINARY} '{ print $2 }')\n        if [ -z \"${DOCKER_CONTAINERS_TOTAL}\" ]; then\n            DOCKER_CONTAINERS_TOTAL=0\n        fi\n\n        LogText \"Result: docker info shows ${DOCKER_CONTAINERS_TOTAL} containers\"\n        DOCKER_CONTAINERS_TOTAL2=$(${DOCKERBINARY} ps -a 2> /dev/null | ${GREPBINARY} -c -v \"CONTAINER\")\n        LogText \"Result: docker ps -a shows ${DOCKER_CONTAINERS_TOTAL2} containers\"\n        if [ ! \"${DOCKER_CONTAINERS_TOTAL}\" = \"${DOCKER_CONTAINERS_TOTAL2}\" ]; then\n            LogText \"Result: difference detected, which is unexpected\"\n            ReportSuggestion \"${TEST_NO}\" \"Test output of both 'docker ps -a' and 'docker info', to determine why they report a different amount of containers\"\n            Display --indent 8 --text \"- Total containers\" --result \"${STATUS_UNKNOWN}\" --color RED\n        else\n            Display --indent 8 --text \"- Total containers\" --result \"${DOCKER_CONTAINERS_TOTAL}\" --color WHITE\n        fi\n\n        # Check running instances\n        DOCKER_CONTAINERS_RUNNING=$(${DOCKERBINARY} ps 2> /dev/null | ${GREPBINARY} -c -v \"CONTAINER\")\n        if [ ${DOCKER_CONTAINERS_RUNNING} -gt 0 ]; then\n            Display --indent 10 --text \"- Running containers\" --result \"${DOCKER_CONTAINERS_RUNNING}\" --color GREEN\n            LogText \"Result: ${DOCKER_CONTAINERS_RUNNING} containers are currently active\"\n            Report \"docker_containers_running=${DOCKER_CONTAINERS_RUNNING}\"\n        else\n            LogText \"Result: no active containers\"\n            Report \"docker_containers_running=0\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CONT-8107\n    # Description : Checking Docker number of unused containers\n    # Notes       : Hardening points are awarded, if there aren't a lot of stopped containers\n    if [ -n \"${DOCKERBINARY}\" -a ${RUN_DOCKER_TESTS} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CONT-8107 --preqs-met ${PREQS_MET} --weight L --network NO --category performance --description \"Check number of Docker containers\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if there aren't too many unused containers on the system\n        if [ ${DOCKER_CONTAINERS_TOTAL} -gt 0 ]; then\n            DOCKER_CONTAINERS_UNUSED=$((DOCKER_CONTAINERS_TOTAL - DOCKER_CONTAINERS_RUNNING))\n            if [ ${DOCKER_CONTAINERS_UNUSED} -gt 10 ]; then\n                ReportSuggestion \"${TEST_NO}\" \"More than 10 unused containers found on the system. Clean up old containers by using output of 'docker ps -a' command\"\n                Display --indent 8 --text \"- Unused containers\" --result \"${DOCKER_CONTAINERS_UNUSED}\" --color RED\n                AddHP 0 2\n            else\n                LogText \"Result: found ${DOCKER_CONTAINERS_UNUSED} unused containers\"\n                Display --indent 8 --text \"- Unused containers\" --result \"${DOCKER_CONTAINERS_UNUSED}\" --color YELLOW\n                AddHP 1 1\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CONT-8108\n    # Description : Checking Docker file permissions\n    # Notes       : /var/run/docker.sock - Usually root as owner, docker as group - should not be world writable\n    if [ -n \"${DOCKERBINARY}\" -a ${RUN_DOCKER_TESTS} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CONT-8108 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check file permissions for Docker files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        NOT_WORLD_WRITABLE=\"${ROOTDIR}var/run/docker.sock\"\n        for FILE in ${NOT_WORLD_WRITABLE}; do\n            LogText \"Test: Check ${FILE}\"\n            if [ -f ${FILE} ]; then\n                LogText \"Result: file ${FILE} found, permissions will be tested\"\n                if IsWorldWritable ${FILE}; then\n                    LogText \"Result: file is writable by others, which is a security risk (e.g. privilege escalation)\"\n                    ReportWarning \"${TEST_NO}\" \"Docker file is world writable\" \"${FILE}\" \"-\"\n                    DOCKER_FILE_PERMISSIONS_WARNINGS=$((DOCKER_FILE_PERMISSIONS_WARNINGS + 1))\n                else\n                    LogText \"Result: file ${FILE} is not writable by others, which is fine\"\n                fi\n            fi\n        done\n        if [ ${DOCKER_FILE_PERMISSIONS_WARNINGS} -gt 0 ]; then\n            Display --indent 4 --text \"- File permissions\" --result \"${STATUS_WARNING}\"S --color YELLOW\n            AddHP 0 5\n        else\n            Display --indent 4 --text \"- File permissions\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 5 5\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_crypto",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Cryptography\n#\n#################################################################################\n#\n    RNG_FOUND=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_CRYPTOGRAPHY}\"\n#\n#################################################################################\n#\n    # Test        : CRYP-7902\n    # Description : check for expired SSL certificates\n    if [ -n \"${OPENSSLBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CRYP-7902 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check expire date of SSL certificates\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT_EXPIRED=0\n        COUNT_TOTAL=0\n        FOUNDPROBLEM=0\n        SKIP=0\n        sSSL_PATHS=$(echo ${SSL_CERTIFICATE_PATHS} | ${SEDBINARY} 's/:space:/__space__/g' | ${SEDBINARY} 's/:/ /g')\n        sSSL_PATHS=$(echo ${sSSL_PATHS} | ${SEDBINARY} 's/^ //' | ${SORTBINARY} -u)\n        LogText \"Paths to scan: ${sSSL_PATHS}\"\n\n        IGNORE_PATHS_PRINT=$(echo ${SSL_CERTIFICATE_PATHS_TO_IGNORE} | ${SEDBINARY} 's/:/, /g' | ${SEDBINARY} 's/__space__/ /g' | ${SEDBINARY} 's/^ //' | ${SORTBINARY} -u)\n        LogText \"Paths to ignore: ${IGNORE_PATHS_PRINT}\"\n\n        for DIR in ${sSSL_PATHS}; do\n            COUNT_DIR=0\n            if [ -d ${DIR} ]; then\n                FileIsReadable ${DIR}\n                if [ ${CANREAD} -eq 1 ]; then\n                    LASTSUBDIR=\"\"\n                    LogText \"Result: found directory ${DIR}\"\n                    # Search for certificate files\n                    FILES=$(${FINDBINARY} ${DIR} -type f 2> /dev/null | ${GREPBINARY} -E \".cer$|.crt$|.der$|.pem$|^cert\" | ${SORTBINARY} | ${SEDBINARY} 's/ /__space__/g')\n                    for FILE in ${FILES}; do\n                        FILE=$(echo ${FILE} | ${SEDBINARY} 's/__space__/ /g')\n                        # See if we need to skip this path\n                        SUBDIR=$(echo ${FILE} | ${AWKBINARY} -F/ 'sub(FS $NF,x)' | ${SEDBINARY} 's/__space__/ /g')\n                        # If we discover a new directory, do evaluation\n                        #Debug \"File   : ${FILE}\"\n                        #Debug \"Lastdir: ${LASTSUBDIR}\"\n                        #Debug \"Curdir : ${SUBDIR}\"\n                        if [ ! \"${SUBDIR}\" = \"${LASTSUBDIR}\" ]; then\n                            SKIP=0\n                            # Now check if this path is on the to-be-ignored list\n                            for D in ${SSL_CERTIFICATE_PATHS_TO_IGNORE}; do\n                                if ContainsString \"${D}\" \"${SUBDIR}\"; then\n                                    SKIP=1\n                                    LogText \"Result: skipping directory (${SUBDIR}) as it is on ignore list\"\n                                fi\n                            done\n                        fi\n                        if [ ${SKIP} -eq 0 ]; then\n                            #Debug \"Testing ${FILE} in path: $SUBDIR\"\n                            COUNT_DIR=$((COUNT_DIR + 1))\n                            FileIsReadable \"${FILE}\"\n                            if [ ${CANREAD} -eq 1 ]; then\n                                # Only check the files that are not installed by a package, unless enabled by profile\n                                if [ ${SSL_CERTIFICATE_INCLUDE_PACKAGES} -eq 1 ] || ! FileInstalledByPackage \"${FILE}\"; then\n                                    echo ${FILE} | ${GREPBINARY} -E -q \".cer$|.der$\"\n                                    CER_DER=$?\n                                    OUTPUT=$(${GREPBINARY} -q 'BEGIN CERT' \"${FILE}\")\n                                    if [ $? -eq 0 -o ${CER_DER} -eq 0 ]; then\n                                        LogText \"Result: file is a certificate file\"\n                                        if [ ${CER_DER} -eq 0 ]; then\n                                            SSL_DER_OPT=\"-inform der\"\n                                        else\n                                            SSL_DER_OPT=\n                                        fi\n                                        FIND=$(${OPENSSLBINARY} x509 -noout ${SSL_DER_OPT} -in \"${FILE}\" -enddate 2> /dev/null | ${GREPBINARY} \"^notAfter\")\n                                        if [ $? -eq 0 ]; then\n                                            # Check certificate where 'end date' has been expired\n                                            FIND=$(${OPENSSLBINARY} x509 -noout ${SSL_DER_OPT} -checkend 0 -in \"${FILE}\" -enddate 2> /dev/null)\n                                            EXIT_CODE=$?\n                                            CERT_CN=$(${OPENSSLBINARY} x509 -noout ${SSL_DER_OPT} -subject -in \"${FILE}\" 2> /dev/null | ${SEDBINARY} -e 's/^subject.*CN=\\([a-zA-Z0-9\\.\\-\\*]*\\).*$/\\1/')\n                                            CERT_NOTAFTER=$(${OPENSSLBINARY} x509 -noout ${SSL_DER_OPT} -enddate -in \"${FILE}\" 2> /dev/null | ${AWKBINARY} -F= '{if ($1==\"notAfter\") { print $2 }}')\n                                            Report \"certificate[]=${FILE}|${EXIT_CODE}|cn:${CERT_CN};notafter:${CERT_NOTAFTER};|\"\n                                            if [ ${EXIT_CODE} -eq 0 ]; then \n                                                LogText \"Result: certificate ${FILE} seems to be correct and still valid\"\n                                            else\n                                                FOUNDPROBLEM=1\n                                                COUNT_EXPIRED=$((COUNT_EXPIRED + 1))\n                                                LogText \"Result: certificate ${FILE} has been expired\"\n                                            fi\n                                        else\n                                            LogText \"Result: skipping tests for this file (${FILE}) as it is most likely not a certificate (is it a key file?)\"\n                                        fi\n                                    else\n                                        LogText \"Result: skipping test for this file (${FILE}) as we could not find 'BEGIN CERT'\"\n                                    fi\n                                fi\n                            else\n                                LogText \"Result: can not read file ${FILE} (no permission)\"\n                            fi\n                        fi\n                        LASTSUBDIR=\"${SUBDIR}\"\n                    done\n                    COUNT_TOTAL=$((COUNT_TOTAL + COUNT_DIR))\n                    LogText \"Result: found ${COUNT_DIR} certificates in ${DIR}\"\n                else\n                    LogText \"Result: can not read path ${DIR} (no permission)\"\n                fi\n            else\n                LogText \"Result: SSL path ${DIR} does not exist\"\n            fi\n        done\n        Report \"certificates=${COUNT_TOTAL}\"\n        LogText \"Result: found a total of ${COUNT_TOTAL} certificates\"\n\n        if [ ${FOUNDPROBLEM} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking for expired SSL certificates [${COUNT_EXPIRED}/${COUNT_TOTAL}]\" --result \"${STATUS_NONE}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Checking for expired SSL certificates [${COUNT_EXPIRED}/${COUNT_TOTAL}]\" --result \"${STATUS_FOUND}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check available certificates for expiration\"\n        fi\n    fi\n\n#\n#################################################################################\n#\n    # Test        : CRYP-7930\n    # Description : Determine if system uses LUKS block device encryption\n    Register --test-no CRYP-7930 --os Linux --weight L --network NO --root-only YES --category security --description \"Determine if system uses LUKS block device encryption\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        CRYPTTABFILE=\"${ROOTDIR}etc/crypttab\"\n        FOUND=0\n\n        # cryptsetup only works as root\n        if [ -n \"${LSBLKBINARY}\" ] && [ -n \"${CRYPTSETUPBINARY}\" ] && [ ${FORENSICS_MODE} -eq 0 ]; then\n            for BLOCK_DEV in $(${LSBLKBINARY} --noheadings --list -o NAME 2> /dev/null | cut -d' ' -f1); do\n                if ${CRYPTSETUPBINARY} isLuks $(${FINDBINARY} /dev/ -name \"${BLOCK_DEV}\" 2> /dev/null) 2> /dev/null; then\n                    LogText \"Result: Found LUKS encrypted block device: ${BLOCK_DEV}\"\n                    Report \"encryption[]=luks,block_device,${BLOCK_DEV}\"\n                    FOUND=$((FOUND +1))\n                else\n                    LogText \"Result: block device ${BLOCK_DEV} is not LUKS encrypted\"\n                fi\n            done\n            unset BLOCK_DEV\n\n        # This will enable us to do a test for forensics or when crypsetup/lsblk are not available\n        elif [ -f ${CRYPTTABFILE} ]; then\n            LogText \"Result: crypttab (${CRYPTTABFILE}) exists\"\n            DATA=$(${GREPBINARY} \"^[a-z]\" ${CRYPTTABFILE} | ${TRBINARY} -cd '[:alnum:]_\\-=,\\n\\t ' | ${SEDBINARY} 's/[[:blank:]]/__space__/g')\n            for LINE in ${DATA}; do\n                LINE=$(echo ${LINE} | ${SEDBINARY} 's/__space__/ /g')\n                if ContainsString \"luks,\" \"${LINE}\"; then\n                    PARTITION=$(echo ${LINE} | ${AWKBINARY} '{print $1}' | ${AWKBINARY} -F_ '{print $1}')\n                    LogText \"Result: Found LUKS encryption on partition ${PARTITION}\"\n                    Report \"encryption[]=luks,partition,${PARTITION}\"\n                    FOUND=$((FOUND +1))\n                fi\n            done\n            unset DATA LINE PARTITION\n        fi\n\n        if [ ${FOUND} -gt 0 ]; then\n            Display --indent 2 --text \"- Found ${FOUND} LUKS encrypted block devices.\" --result OK --color WHITE\n        fi\n        unset FOUND\n    fi\n#\n#################################################################################\n#\n    # Test        : CRYP-7931\n    # Description : Determine if system uses encrypted swap\n    if [ -e \"${SWAPONBINARY}\" -a -e \"${CRYPTSETUPBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CRYP-7931 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description \"Determine if system uses encrypted swap\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        ENCRYPTED_SWAPS=0\n        UNENCRYPTED_SWAPS=0\n        # Redirect errors, as RHEL 5/6 and others don't have the --show option\n        SWAPS=$(${SWAPONBINARY} --show=NAME --noheadings 2> /dev/null)\n        if [ $? -eq 0 ]; then\n            for BLOCK_DEV in ${SWAPS}; do\n                if ${CRYPTSETUPBINARY} isLuks \"${BLOCK_DEV}\" 2> /dev/null; then\n                    LogText \"Result: Found LUKS encrypted swap device: ${BLOCK_DEV}\"\n                    ENCRYPTED_SWAPS=$((ENCRYPTED_SWAPS + 1))\n                    Report \"encrypted_swap[]=${BLOCK_DEV},LUKS\"\n                elif ${CRYPTSETUPBINARY} status \"${BLOCK_DEV}\" 2> /dev/null | ${GREPBINARY} -q \"cipher:\"; then\n                    LogText \"Result: Found non-LUKS encrypted swap device: ${BLOCK_DEV}\"\n                    ENCRYPTED_SWAPS=$((ENCRYPTED_SWAPS + 1))\n                    Report \"encrypted_swap[]=${BLOCK_DEV},other\"\n                else\n                    LogText \"Result: Found unencrypted swap device: ${BLOCK_DEV}\"\n                    UNENCRYPTED_SWAPS=$((UNENCRYPTED_SWAPS +1))\n                    Report \"non_encrypted_swap[]=${BLOCK_DEV}\"\n                fi\n            done\n            Display --indent 2 --text \"- Found ${ENCRYPTED_SWAPS} encrypted and ${UNENCRYPTED_SWAPS} unencrypted swap devices in use.\" --result OK --color WHITE\n        else\n            LogText \"Result: skipping testing as swapon returned an error.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CRYP-7932\n    # Description : Determine if system has enabled macOS FileVault encryption\n    Register --test-no CRYP-7932 --os macOS --weight L --network NO --category crypto --description \"Determine if system has enabled macOS FileVault encryption\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if command -v fdesetup &> /dev/null; then\n            case $(fdesetup status) in\n                *\"FileVault is On.\"*)\n                    LogText \"Result: FileVault is enabled.\"\n                    Display --indent 2 --text \"- FileVault is enabled.\" --result \"${STATUS_OK}\" --color GREEN\n                    Report \"encryption[]=filevault\"\n                    AddHP 3 3\n                    ;;\n                *)\n                    LogText \"Result: FileVault is not enabled.\"\n                    Display --indent 2 --text \"- FileVault is not enabled.\" --result \"${STATUS_WARNING}\" --color RED\n                    AddHP 0 3\n                    ;;\n            esac\n        else\n            LogText \"Result: fdesetup command not found. Unable to determine FileVault status.\"\n            Display --indent 2 --text \"- Unable to determine FileVault status (fdesetup command not found).\" --result \"${STATUS_WARNING}\" --color YELLOW\n            AddHP 0 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CRYP-8002\n    # Description : Gather available kernel entropy\n    Register --test-no CRYP-8002 --os Linux --weight L --network NO --root-only NO --category security --description \"Gather available kernel entropy\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}proc/sys/kernel/random/entropy_avail ]; then\n            DATA=$(${AWKBINARY} '$1 ~ /^[0-9]+$/ {print $1}' ${ROOTDIR}proc/sys/kernel/random/entropy_avail)\n            if [ -n \"${DATA}\" ]; then\n                LogText \"Result: found kernel entropy value of ${DATA}\"\n                Report \"kernel_entropy=${DATA}\"\n                if [ ${DATA} -gt 200 ]; then\n                    Display --indent 2 --text \"- Kernel entropy is sufficient\" --result \"${STATUS_YES}\" --color GREEN\n                else\n                    Display --indent 2 --text \"- Kernel entropy is sufficient\" --result \"${STATUS_NO}\" --color YELLOW\n                    # TODO - enable suggestion when information on website is available\n                fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CRYP-8004\n    # Description : Test for presence of hardware random number generators\n    Register --test-no CRYP-8004 --os Linux --weight L --network NO --root-only NO --category security --description \"Presence of hardware random number generators\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: looking for ${ROOTDIR}sys/class/misc/hw_random/rng_current\"\n        if [ -f \"${ROOTDIR}sys/class/misc/hw_random/rng_current\" ]; then\n            DATA=$(${HEADBINARY} -n 1 ${ROOTDIR}sys/class/misc/hw_random/rng_current | ${TRBINARY} -d '[[:cntrl:]]')\n            if [ \"${DATA}\" != \"none\" ]; then\n                LogText \"Result: positive match, found RNG: ${DATA}\"\n                if IsRunning \"rngd\"; then\n                    Display --indent 2 --text \"- HW RNG & rngd\" --result \"${STATUS_YES}\" --color GREEN\n                    LogText \"Result: rngd is running\"\n                    RNG_FOUND=1\n                else\n                    Display --indent 2 --text \"- HW RNG & rngd\" --result \"${STATUS_NO}\" --color YELLOW\n                    # TODO - enable suggestion when website has listing for this control\n                    # ReportSuggestion \"${TEST_NO}\" \"Utilize hardware random number generation by running rngd\"\n                fi\n            else\n                Display --indent 2 --text \"- HW RNG & rngd\" --result \"${STATUS_NO}\" --color YELLOW\n                LogText \"Result: no HW RNG available\"\n            fi\n        else\n            Display --indent 2 --text \"- HW RNG & rngd\" --result \"${STATUS_NO}\" --color RED\n            LogText \"Result: could not find ${ROOTDIR}sys/class/misc/hw_random/rng_current\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CRYP-8005\n    # Description : Test for presence of software pseudo random number generators\n    Register --test-no CRYP-8005 --os Linux --weight L --network NO --root-only NO --category security --description \"Presence of software pseudo random number generators\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: looking for software pseudo random number generators\"\n        FOUND=\"\"\n        for SERVICE in audio-entropyd haveged jitterentropy-rngd; do\n            # Using --full as jitterentropy-rngd would otherwise not match\n            if IsRunning --full \"${SERVICE}\"; then\n                FOUND=\"${FOUND} ${SERVICE}\"\n            fi\n        done\n        if [ -z \"${FOUND}\" ]; then\n            Display --indent 2 --text \"- SW prng\" --result \"${STATUS_NO}\" --color YELLOW\n            # ReportSuggestion \"${TEST_NO}\" \"Utilize software pseudo random number generators\"\n        else\n            RNG_FOUND=1\n            Display --indent 2 --text \"- SW prng\" --result \"${STATUS_YES}\" --color GREEN\n            LogText \"Result: found ${FOUND} running\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : CRYP-8006\n    # Description : Check that the MemoryOverwriteRequest-bit is set to protect against cold-boot attacks\n    Register --test-no CRYP-8006 --os Linux --weight L --network NO --root-only NO --category security --description \"MemoryOverwriteRequest-bit set\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        MOR_CONTROL=\"${ROOTDIR}sys/firmware/efi/efivars/MemoryOverwriteRequestControl-e20939be-32d4-41be-a150-897f85d49829\"\n        LogText \"Test: looking for ${MOR_CONTROL}\"\n        if [ -f \"${MOR_CONTROL}\" ]; then\n            DATA=$(od -An --skip-bytes=4 \"$MOR_CONTROL\")\n            if [ \"$DATA\" = \" 000001\" ]; then\n                LogText \"Result: MOR-bit set\"\n                Display --indent 2 --text \"MOR-bit set\" --result \"${STATUS_YES}\" --color GREEN\n            elif [ \"$DATA\" = \" 000000\" ]; then\n                LogText \"Result: MOR-bit not set!\"\n                Display --indent 2 --text \"MOR-bit set\" --result \"${STATUS_NO}\" --color RED\n            else\n                LogText \"Result: MOR-bit unknown. Found: $DATA\"\n                Display --indent 2 --text \"MOR-bit set\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n            fi\n        else\n            LogText \"Result: could not find ${MOR_CONTROL}\"\n            Display --indent 2 --text \"- MOR variable not found\" --result \"${STATUS_WEAK}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    Report \"rng_found=${RNG_FOUND}\"\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_custom.template",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n# This is the custom tests file and serves as a template.\n#\n# The language used in bourne shell (not bash). That means that almost everything\n# you could use in bash, will also work here. Arrays and advanced substitutions\n# will not work.\n#\n# How to use:\n#\n# Copy this file to the 'include' directory and name it tests_custom\n# Find your includedir with: lynis show includedir\n#\n#################################################################################\n#\n# Tips:\n#\n# Use each test ID only once in the Register function and prefix them with CUST\n#\n# Use big steps (e.g. 10) in numbering, so you can easily put in tests later.\n#\n# Help the community and share your checks on https://github.com/CISOfy/lynis/\n#\n#################################################################################\n#\n    # Test        : CUST-0010\n    # Description : We show some lines on the screen\n\n    # Register our first custom test\n    # We consider it to be a lightweight test (no heavy IO, or long searches), no network connection needed\n    # --test-no   unique ID\n    # --weight    L/M/H\n    # --category  category (e.g. performance, privacy, security)\n    Register --test-no CUST-0010 --weight L --network NO --category security --description \"A test for displaying things on screen\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # The Display function makes it easy to show something on screen, with colors.\n        # --indent  defines amount of spaces\n        # --text    text to be displayed on screen\n        # --result  text at end of line\n        # --color   color of result text\n        Display --indent 2 --text \"- Checking if everything is OK...\" --result \"${STATUS_OK}\" --color GREEN\n        Display --indent 4 --text \"This shows one level deeper \" --result \"${STATUS_NO}\" --color YELLOW\n        Display --indent 6 --text \"And even deeper\" --result \"${STATUS_WARNING}\" --color RED\n    fi\n#\n#################################################################################\n#\n    # Test        : CUST-0020\n    # Description : We show some lines on the screen\n    Register --test-no CUST-0020 --weight L --network NO --category security --description \"Dealing with files and directories\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        # With -d we can test for directories, -f is for files, -L for symlinks.\n\n        # Most tests use the \"if-then-else\". If something is true, take one step, otherwise the other.\n        if DirectoryExists /tmp; then\n            LogText \"Result: we have a temporary directory\"\n        else\n            LogText \"Result: no temporary directory found\"\n        fi\n\n        # Instead of ready-to-use functions, you can use normal shell script tests, like:\n        # if [ -f /etc/file ]; then                     =  Test if file exists\n        # if [ -d /var/run/mydirectory ]; then          =  Test if directory exists\n        # if [ -L /var/run/mydirectory ]; then          =  Test if symlink exists\n        # if [ ${MYVARIABLE} -eq 1 ]; then              =  Test if variable is set to 1 (make sure it was defined at beginning of test)\n        # if [ \"${MYVARIABLE}\" = \"Value\" ]; then        =  Test if variable is equal to specific value\n\n        # Let's test for a file. We like to find at least one file (file1 or file2)\n        if FileExists /etc/file1; then\n            LogText \"Result: Found file /etc/file1\"\n        elif FileExists /etc/file2; then\n            LogText \"Result: Found file /etc/file2\"\n        else\n            LogText \"Result: both /etc/file1 and /etc/file2 were not found\"\n            # Show a warning on screen and in the report. We can specify a detail and how to solve it.\n            ReportWarning \"${TEST_NO}\" \"No file /etc/file1 or /etc/file2 available\"\n        fi\n\n        # If a single value is stored in a variable, using 'case' is very effective.\n        # Let's check for a predefined variable OS, which is defined by Lynis\n        case ${OS} in\n            # Only match one value\n            \"Linux\")\n                LogText \"Found Linux\"\n                Display --indent 2 --text \"OS: Linux\" --result \"${STATUS_OK}\" --color GREEN\n            ;;\n            # Matching several platforms\n            \"FreeBSD\" | \"NetBSD\" | \"OpenBSD\")\n                LogText \"Found an operating system based on BSD\"\n                Display --indent 2 --text \"OS: *BSD\" --result \"${STATUS_OK}\" --color GREEN\n            ;;\n            # Catch-all for other values\n            *)\n                LogText \"Found another operating system\"\n                ReportSuggestion \"${TEST_NO}\" \"Check if this process is running\" \"apache\" \"url:https://cisofy.com/support/\"\n            ;;\n        esac\n\n    fi\n#\n#################################################################################\n#\n    # Add a new section to the screen output\n    InsertSection \"Custom tests - Other\"\n#\n#################################################################################\n#\n    # Test        : CUST-0040\n    # Description : Our second test, with a prerequisite test\n\n    # First check if OPENSSLBINARY is known as a prerequisite for this test\n    # ! means \"not\". So if the binary is known, the prerequisite is matched. Otherwise we set it to NO and define a reason why we skipped this test\n\n    if [ ! \"${OPENSSLBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No OpenSSL binary found\"; fi\n    Register --test-no CUST-0040 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight M --network NO --category security --description \"Description of custom test\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Set variable to zero, to indicate that we have no problems found (yet)\n        FOUNDPROBLEM=0\n        DIR=\"/my/path\"\n        LogText \"Test: we are going to check if we can find a particular directory (${DIR})\"\n        # Check if a directory exists\n        if DirectoryExists ${DIR}; then\n            LogText \"Result: log entry for easier debugging or additional information\"\n        else\n            FOUNDPROBLEM=1\n            LogText \"Result: directory ${DIR} was not found!\"\n            ReportWarning \"${TEST_NO}\" \"This is a test warning line\" \"${DIR}\" \"text:Create directory ${DIR}\"\n        fi\n\n        if [ ${FOUNDPROBLEM} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking if everything is OK...\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Checking if everything is OK...\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"This is a suggestion\"\n        fi\n    fi\n#\n#################################################################################\n#\n\n# Wait for keypress (unless --quick is being used)\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_databases",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Databases\n#\n#################################################################################\n#\n    # Paths to DATADIR\n    sMYSQLDBPATHS=\"${ROOTDIR}var/lib/mysql\"\n    # Paths to my.cnf\n    sMYCNFLOCS=\"${ROOTDIR}etc/mysql/my.cnf ${ROOTDIR}usr/etc/my.cnf\"\n    REDIS_CONFIGURATION_FILES=\"\"\n    REDIS_CONFIGURATION_FOUND=0\n\n    MYSQL_RUNNING=0\n    DATABASE_ENGINE_RUNNING=0\n    MONGODB_RUNNING=0\n    POSTGRESQL_RUNNING=0\n    ORACLE_RUNNING=0\n    DB2_RUNNING=0\n    REDIS_RUNNING=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_DATABASES}\"\n\n    # Test        : DBS-1804\n    # Description : Check if MySQL is being used\n    Register --test-no DBS-1804 --weight L --network NO --category security --description \"Checking active MySQL process\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} -E \"mariadb|mysqld|mysqld_safe\" | ${GREPBINARY} -v \"grep\")\n        if [ -z \"${FIND}\" ]; then\n            if [ ${DEBUG} -eq 1 ]; then Display --indent 2 --text \"- MySQL process status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE --debug; fi\n            LogText \"Result: MySQL process not active\"\n        else\n            Display --indent 2 --text \"- MySQL process status\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: MySQL is active\"\n            MYSQL_RUNNING=1\n            DATABASE_ENGINE_RUNNING=1\n            Report \"mysql_running=${MYSQL_RUNNING}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1808\n    # Description : Check MySQL data directory\n    #Register --test-no DBS-1808 --weight L --network NO --category security --description \"Checking MySQL data directory\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    #fi\n#\n#################################################################################\n#\n    # Test        : DBS-1812\n    # Description : Check data directory permissions\n    #Register --test-no DBS-1812 --weight L --network NO --category security --description \"Checking MySQL data directory permissions\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    #fi\n#\n#################################################################################\n#\n    # Test        : DBS-1816\n    # Description : Check empty MySQL root password\n    # Notes       : Only perform test when MySQL is running and client is available\n    if [ -n \"${MYSQLCLIENTBINARY}\" -a ${MYSQL_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"MySQL not installed, or not running\"; fi\n    Register --test-no DBS-1816 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Checking MySQL root password\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Trying to login to local MySQL server without password\"\n\n        # \"-u root --password=\" avoids ~/.my.cnf authentication settings\n        # \"plugin = 'mysql_native_password' AND authentication_string = ''\" avoids false positives when secure plugins are used\n        FIND=$(${MYSQLCLIENTBINARY} --default-auth=mysql_native_password  --no-defaults -u root --password= --silent --batch --execute=\"SELECT count(*) FROM mysql.user WHERE user = 'root' AND plugin = 'mysql_native_password' AND authentication_string = ''\" mysql > /dev/null 2>&1; echo $?)\n        if [ \"${FIND}\" = \"0\" ]; then\n           LogText \"Result: Login succeeded, no MySQL root password set!\"\n           ReportWarning \"${TEST_NO}\" \"No MySQL root password set\"\n           Display --indent 4 --text \"- Checking empty MySQL root password\" --result \"${STATUS_WARNING}\" --color RED\n           AddHP 0 5\n        else\n            LogText \"Result: Login did not succeed, so a MySQL root password is set\"\n            if IsVerbose; then Display --indent 4 --text \"- Checking MySQL root password\" --result \"${STATUS_OK}\" --color GREEN; fi\n            AddHP 2 2\n        fi\n    else\n        LogText \"Test skipped, MySQL daemon not running or no MySQL client available\"\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1818\n    # Description : Check MongoDB status\n    Register --test-no DBS-1818 --weight L --network NO --category security --description \"Check status of MongoDB server\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning \"mongod\"; then\n            MONGODB_RUNNING=1\n            DATABASE_ENGINE_RUNNING=1\n            Report \"mongodb_running=1\"\n            Display --indent 2 --text \"- MongoDB status\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n    fi\n\n    # Test        : DBS-1820\n    # Description : Check empty MongoDB authorization\n    # Notes       : Authentication can be set via command line or configuration file\n    Register --test-no DBS-1820 --weight L --network NO --category security --description \"Check for authorization in MongoDB\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        MONGODB_AUTHORIZATION_ENABLED=0\n        if [ ${MONGODB_RUNNING} -eq 1 ]; then\n\n            MONGO_CONF_FILES=\"${ROOTDIR}etc/mongod.conf ${ROOTDIR}etc/mongodb.conf\"\n            for FILE in ${MONGO_CONF_FILES}; do\n                if [ -f ${FILE} ]; then\n                    LogText \"Result: found MongoDB configuration file (${FILE})\"\n                    # YAML with quotes\n                    if [ ${MONGODB_AUTHORIZATION_ENABLED} -eq 0 ]; then\n                        LogText \"Test: determine authorization setting in new style YAML format\"\n                        AUTH_IN_CONFIG=$(${GREPBINARY} \"authorization: \\\"enabled\\\"\" ${FILE} | ${GREPBINARY} -E -v \"(^#|#auth)\")\n                        if HasData \"${AUTH_IN_CONFIG}\"; then\n                            LogText \"Result: GOOD, found authorization option enabled in configuration file (YAML format with quotes)\"\n                            MONGODB_AUTHORIZATION_ENABLED=1\n                        fi\n                    fi\n                    # YAML without quotes\n                    if [ ${MONGODB_AUTHORIZATION_ENABLED} -eq 0 ]; then\n                        AUTH_IN_CONFIG=$(${GREPBINARY} \"authorization: enabled\" ${FILE} | ${GREPBINARY} -E -v \"(^#|#auth)\")\n                        if HasData \"${AUTH_IN_CONFIG}\"; then\n                            LogText \"Result: GOOD, found authorization option enabled in configuration file (YAML format without quotes)\"\n                            MONGODB_AUTHORIZATION_ENABLED=1\n                        fi\n                    fi\n                    # Old style\n                    if [ ${MONGODB_AUTHORIZATION_ENABLED} -eq 0 ]; then\n                        LogText \"Result: did NOT find authorization option enabled in configuration file (with YAML format)\"\n                        LogText \"Test: now searching for old style configuration (auth = true) in configuration file\"\n                        AUTH_IN_CONFIG=$(${GREPBINARY} \"auth = true\" ${FILE} | ${GREPBINARY} -v \"noauth\" | ${GREPBINARY} -E -v \"(^#|#auth)\")\n                        if IsEmpty \"${AUTH_IN_CONFIG}\"; then\n                            LogText \"Result: did NOT find auth = true in configuration file\"\n                        else\n                            LogText \"Result: GOOD, found authorization option enabled in configuration file (old format)\"\n                            MONGODB_AUTHORIZATION_ENABLED=1\n                        fi\n                    fi\n                else\n                    LogText \"Result: configuration file ${FILE} not found\"\n                fi\n            done\n\n            # Now check authorization on the command line\n            if [ ${MONGODB_AUTHORIZATION_ENABLED} -eq 0 ]; then\n                if HasData \"${PGREPBINARY}\"; then\n                    AUTH_ON_CMDLINE=$(for I in $(${PGREPBINARY} mongo); do cat /proc/${I}/cmdline | xargs -0 echo | ${GREPBINARY} -E \"\\-\\-auth( |$)\"; done)\n                    if [ -n \"${AUTH_ON_CMDLINE}\" ]; then LogText \"Result: found authorization enabled via mongod parameter\"; MONGODB_AUTHORIZATION_ENABLED=1; fi\n                else\n                    LogText \"Result: skipped this part of the test, as pgrep is not available\"\n                fi\n            fi\n            if [ ${MONGODB_AUTHORIZATION_ENABLED} -eq 0 ]; then\n                LogText \"Result: no authorization enabled via parameter or configuration file\"\n                Report \"mongodb_authorization_disabled=1\"\n                ReportWarning \"${TEST_NO}\" \"MongoDB instance allows any user to access databases\"\n                Display --indent 4 --text \"- Checking MongoDB authorization\" --result \"${STATUS_DISABLED}\" --color RED\n            else\n                if IsVerbose; then Display --indent 4 --text \"- Checking MongoDB authorization\" --result \"${STATUS_ENABLED}\" --color GREEN; fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1826\n    # Description : Check if PostgreSQL is being used\n    Register --test-no DBS-1826 --weight L --network NO --category security --description \"Checking active PostgreSQL processes\"\n    for PROCES in postgres postmaster\n    do\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning \"${PROCES}\"; then\n            Display --indent 2 --text \"- PostgreSQL processes status\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: PostgreSQL is active\"\n            POSTGRESQL_RUNNING=1\n            DATABASE_ENGINE_RUNNING=1\n            Report \"postgresql_running=${POSTGRESQL_RUNNING}\"\n        else\n            if [ ${DEBUG} -eq 1 ]; then Display --indent 2 --text \"- PostgreSQL processes status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE --debug; fi\n            LogText \"Result: PostgreSQL process ${PROCES} not active\"\n        fi\n    fi\n    done\n#\n#################################################################################\n#\n    # Test        : DBS-1828\n    # Description : Test PostgreSQL configuration file(s)\n    #\n    # Authentication:\n    # /var/lib/pgsql/data/pg_hba.conf\n    #\n    # Configuration\n    # Arch            /var/lib/postgres/data/postgresql.conf\n    # CentOS/Fedora   /var/lib/pgsql/data/postgresql.conf\n    # Ubuntu          /etc/postgresql/x.y/main/postgresql.conf\n    # FreeBSD         /var/db/postgres/data[0-9][0-9]/postgresql.conf\n\n    if [ \"${POSTGRESQL_RUNNING}\" -eq 1 ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"PostgreSQL not installed or not running\"; fi\n\n    Register --test-no DBS-1828 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Test PostgreSQL configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND_PATHS=$(${LSBINARY} -d ${ROOTDIR}usr/local/pgsql/data* 2> /dev/null)\n        FIND_PATHS=\"${FIND_PATHS} ${ROOTDIR}etc/postgres ${ROOTDIR}etc/postgresql ${ROOTDIR}var/lib/postgres/data ${ROOTDIR}usr/local/pgsql/data ${ROOTDIR}var/lib/pgsql/data ${ROOTDIR}var/db/postgres/data[0-9][0-9]\"\n        CONFIG_FILES=$(${FINDBINARY} -L ${FIND_PATHS} -type f -name \"*.conf\" -print0 2> /dev/null | ${TRBINARY} -cd '[:print:]\\0' | ${TRBINARY} -d '\\n' | ${TRBINARY} '\\0' '\\n' | xargs -I'{}' sh -c 'test -r \"{}\" && echo \"{}\"' | ${SEDBINARY} \"s/ /:space:/g\")\n        for CF in ${CONFIG_FILES}; do\n            Report \"postgresql_config_file[]=${CF}\"\n            LogText \"Found configuration file (${CF})\"\n            if IsWorldReadable ${CF}; then\n                LogText \"Result: configuration file ${CF} is world readable, this might leak sensitive information!\"\n                ReportWarning \"${TEST_NO}\" \"PostgreSQL configuration file ${CF} is world readable and might leak sensitive details\" \"${CF}\" \"Use chmod 600 to change file permissions\"\n            else\n                LogText \"Result: great, configuration file ${CF} is not world readable\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1840\n    # Description : Check if Oracle is being used\n    # Notes       : tnslsnr: Oracle listener\n    #               pmon: process monitor\n    #               smon: system monitor\n    #               dbwr: database writer\n    #               lgwr: log writer\n    #               arch: archiver (optional)\n    #               ckpt: checkpoint (optional)\n    #               reco: recovery (optional)\n    Register --test-no DBS-1840 --weight L --network NO --category security --description \"Checking active Oracle processes\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} -E \"ora_pmon|ora_smon|tnslsnr\" | ${GREPBINARY} -v \"grep\")\n        if [ -z \"${FIND}\" ]; then\n            if [ ${DEBUG} -eq 1 ]; then Display --indent 2 --text \"- Oracle processes status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE --debug; fi\n            LogText \"Result: Oracle process(es) not active\"\n        else\n            Display --indent 2 --text \"- Oracle processes status\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Oracle is active\"\n            ORACLE_RUNNING=1\n            DATABASE_ENGINE_RUNNING=1\n            Report \"oracle_running=${ORACLE_RUNNING}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1842\n    # Description : Check Oracle home paths from oratab\n    #Register --test-no DBS-1842 --weight L --network NO --category security --description \"Checking Oracle home paths\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    # if [ -f /etc/oratab ]; then\n    #  FIND=$(${GREPBINARY} -v \"#\" /etc/oratab | ${AWKBINARY} -F: \"{ print $2 }\")\n    # fi\n    #fi\n#\n#################################################################################\n#\n    # Test        : DBS-1860\n    # Description : Checks if a DB2 instance is currently running\n    Register --test-no DBS-1860 --weight L --network NO --category security --description \"Checking active DB2 instances\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning db2sysc; then\n            Display --indent 2 --text \"- DB2 instance running\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: At least one DB2 instance is running\"\n            DB2_RUNNING=1\n            DATABASE_ENGINE_RUNNING=1\n            Report \"db2_running=${DB2_RUNNING}\"\n        else\n            if [ ${DEBUG} -eq 1 ]; then Display --indent 2 --text \"- DB2 instance running\" --result \"${STATUS_NOT_FOUND}\" --color WHITE --debug; fi\n            LogText \"Result: No DB2 instances are running\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1880\n    # Description : Determine if redis is running\n    Register --test-no DBS-1880 --weight L --network NO --category security --description \"Check for active Redis server\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning redis-server; then\n            Display --indent 2 --text \"- Redis (server) status\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Redis is running\"\n            REDIS_RUNNING=1\n            DATABASE_ENGINE_RUNNING=1\n            Report \"redis_server_running=${REDIS_RUNNING}\"\n        else\n            if [ ${DEBUG} -eq 1 ]; then Display --indent 2 --text \"- Redis (server) status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE --debug; fi\n            LogText \"Result: No Redis processes are running\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1882\n    # Description : Determine Redis configuration\n    if [ ${REDIS_RUNNING} -eq 1 ]; then PREQS_METS=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"Redis not running\"; fi\n    Register --test-no DBS-1882 --weight L --network NO --preqs-met \"${PREQS_MET}\" --skip-reason \"${SKIPREASON}\" --category security --description \"Redis configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        PATHS=\"${ROOTDIR}etc/redis ${ROOTDIR}usr/local/etc ${ROOTDIR}usr/local/etc/redis ${ROOTDIR}usr/local/redis/etc\"\n        if [ ${QNAP_DEVICE} -eq 1 ]; then\n            PATHS=\"${PATHS} ${ROOTDIR}share/CACHEDEV1_DATA/.qpkg/QKVM/usr/etc/redis.conf\"\n        fi\n        if [ -d \"${ROOTDIR}snap\" ]; then\n          for SNAP_PATH in $(${FINDBINARY} ${ROOTDIR}snap -name 'redis.conf' -type f | ${SEDBINARY} 's/redis.conf$//g'); do\n            PATHS=\"${PATHS} ${SNAP_PATH}\"\n          done\n        fi\n\n        ALLFILES=$(${LSBINARY} ${ROOTDIR}etc/redis.conf 2> /dev/null)\n        FOUND=0\n        for DIR in ${PATHS}; do\n            LogText \"Action: scanning directory (${DIR}) for Redis configuration files\"\n            FILES=$(${LSBINARY} ${DIR}/*.conf 2> /dev/null)\n            if [ -n \"${FILES}\" ]; then\n                ALLFILES=\"${ALLFILES} ${FILES}\"\n            else\n                LogText \"Result: no configuration files found in this directory\"\n            fi\n        done\n        for CONFFILE in ${ALLFILES}; do\n            if FileIsReadable ${CONFFILE}; then\n                LogText \"Action: checking if ${CONFFILE} is a Sentinel configuration file\"\n                # Exclude Sentinel configuration file\n                FIND=$(${GREPBINARY} \"^sentinel \" ${CONFFILE})\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: file is a Sentinel configuration file, skipping it\"\n                else\n                    LogText \"Result: file is NOT a Sentinel configuration file. Now scanning if it is a Redis configuration file\"\n                    FIND=$(${GREPBINARY} \"Redis\" ${CONFFILE})\n                    if [ -n \"${FIND}\" ]; then\n                        REDIS_CONFIGURATION_FILES=\"${REDIS_CONFIGURATION_FILES} ${CONFFILE}\"\n                        REDIS_CONFIGURATION_FOUND=1\n                        LogText \"Result: found a Redis configuration file (${CONFFILE})\"\n                    else\n                        LogText \"Result: this file does not look like a Redis file  (${CONFFILE})\"\n                    fi\n                fi\n            else\n                LogText \"Could not read this file, so skipping it\"\n            fi\n        done\n        # Sort the list of discovered configuration files so we can make them unique\n        REDIS_CONFIGURATION_FILES=$(echo ${REDIS_CONFIGURATION_FILES} | ${SEDBINARY} 's/^ //' | ${TRBINARY} ' ' '\\n' | ${SORTBINARY} -u | ${TRBINARY} '\\n' ' ')\n        for FILE in ${REDIS_CONFIGURATION_FILES}; do\n            if IsWorldReadable ${FILE}; then\n                LogText \"Result: configuration file ${FILE} is world readable, this might leak sensitive information!\"\n                ReportWarning \"${TEST_NO}\" \"Redis configuration file ${FILE} is world readable and might leak sensitive details\" \"${FILE}\" \"Use chmod 640 to change file permissions\"\n            else\n                LogText \"Result: great, configuration file ${FILE} is not world readable\"\n            fi\n        done\n        if [ ${REDIS_CONFIGURATION_FOUND} -eq 0 ]; then ReportException \"${TEST_NO}\" \"Found Redis, but no configuration file. Report this if you know where it is located on your system.\"; fi\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1884\n    # Description : Determine Redis configuration option: requirepass\n    if [ ${REDIS_RUNNING} -eq 1 -a ${REDIS_CONFIGURATION_FOUND} -eq 1 ]; then PREQS_METS=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"Redis not running, or no configuration file found\"; fi\n    Register --test-no DBS-1884 --weight L --network NO --preqs-met \"${PREQS_MET}\" --skip-reason \"${SKIPREASON}\" --category security --description \"Redis: requirepass option configured\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for FILE in ${REDIS_CONFIGURATION_FILES}; do\n            if FileIsReadable ${FILE}; then\n                if SearchItem \"^requirepass\" \"${FILE}\" \"--sensitive\"; then\n                    LogText \"Result: found 'requirepass' configured\"\n                    AddHP 3 3\n                    Display --indent 4 --text \"- Redis (requirepass configured)\" --result \"${STATUS_FOUND}\" --color GREEN\n                    Report \"redis_requirepass=1\"\n                else\n                    AddHP 0 3\n                    Display --indent 4 --text \"- Redis (requirepass configured)\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Configure the 'requirepass' setting for Redis\" \"${FILE}\" \"text:configure 'requirepass' setting in ${FILE}\"\n                    Report \"redis_requirepass=0\"\n                fi\n            else\n                LogText \"Result: test skipped, as we can't read configuration file\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1886\n    # Description : Determine Redis configuration option: rename-command CONFIG\n    if [ ${REDIS_RUNNING} -eq 1 -a ${REDIS_CONFIGURATION_FOUND} -eq 1 ]; then PREQS_METS=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"Redis not running, or no configuration found\"; fi\n    Register --test-no DBS-1886 --weight L --network NO --preqs-met \"${PREQS_MET}\" --skip-reason \"${SKIPREASON}\" --category security --description \"Redis: rename-command CONFIG used\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for FILE in ${REDIS_CONFIGURATION_FILES}; do\n            if FileIsReadable ${FILE}; then\n                if SearchItem \"^rename-command CONFIG\" \"${FILE}\" \"--sensitive\"; then\n                    LogText \"Result: found 'rename-command CONFIG' configured\"\n                    AddHP 3 3\n                    Display --indent 4 --text \"- Redis (rename of CONFIG command)\" --result \"${STATUS_FOUND}\" --color GREEN\n                    Report \"redis_rename_command_config=1\"\n                else\n                    AddHP 0 3\n                    Display --indent 4 --text \"- Redis (rename of CONFIG command)\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Use the 'rename-command CONFIG' setting for Redis\" \"${FILE}\" \"text:configure 'rename-command CONFIG' in ${FILE}\"\n                    Report \"redis_rename_command_config=0\"\n                fi\n            else\n                LogText \"Result: test skipped, as we can't read configuration file\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : DBS-1888\n    # Description : Determine Redis configuration option: bind on localhost\n    if [ ${REDIS_RUNNING} -eq 1 -a ${REDIS_CONFIGURATION_FOUND} -eq 1 ]; then PREQS_METS=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"Redis not running, or no configuration found\"; fi\n    Register --test-no DBS-1888 --weight L --network NO --preqs-met \"${PREQS_MET}\" --skip-reason \"${SKIPREASON}\" --category security --description \"Redis: bind on localhost\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for FILE in ${REDIS_CONFIGURATION_FILES}; do\n            if FileIsReadable ${FILE}; then\n                if SearchItem \"^bind (localhost|127\\.)\" \"${FILE}\" \"--sensitive\"; then\n                    LogText \"Result: found 'bind on localhost' configured\"\n                    AddHP 3 3\n                    Display --indent 4 --text \"- Redis (bind on localhost)\" --result \"${STATUS_FOUND}\" --color GREEN\n                    Report \"redis_bind_localhost=1\"\n                else\n                    AddHP 0 3\n                    Display --indent 4 --text \"- Redis (bind on localhost)\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"Use 'bind' setting to listen on localhost for Redis instance\" \"${FILE}\" \"text:configure 'bind localhost' in ${FILE}\"\n                    Report \"redis_bind_localhost=0\"\n                fi\n            else\n                LogText \"Result: test skipped, as we can't read configuration file\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    if [ ${DATABASE_ENGINE_RUNNING} -eq 0 ]; then\n        Display --indent 4 --text \"No database engines found\"\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_dns",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# DNS\n#\n#################################################################################\n#\n#    # TODO create records on test domain\n#    # TODO after update even IP match can be checked to detect hijacking\n#    SIGOKDNS=\"sigok.example.org\"      # address with good DNSSEC signature\n#    SIGFAILDNS=\"sigfail.example.org\"  # address with bad  DNSSEC signature\n#    TIMEOUT=\";; connection timed out; no servers could be reached\"\n#\n#################################################################################\n#\n#    InsertSection \"DNS\"\n#\n#################################################################################\n#\n#    # Test        : DNS-1600\n#    # Description : Validate DNSSEC signature is checked\n#    Register --test-no DNS-1600 --weight L --network YES --category security --description \"Validate DNSSEC igniture is checked\"\n#    if [ \"${SKIPTEST}\" -eq 0 ]; then\n#        if [ -n \"${DIGBINARY}\" ]; then\n#\n#            GOOD=$(\"${DIGBINARY}\" +short +time=1 $SIGOKDNS)\n#            BAD=$(\"${DIGBINARY}\" +short +time=1 $SIGFAILDNS)\n#\n#            if [ \"${GOOD}\" = \"${TIMEOUT}\" -a \"${BAD}\" = \"${TIMEOUT}\" ]; then\n#                LogText \"Result: received timeout, can't determine DNSSEC validation\"\n#                Display --indent 4 --text \"- Checking DNSSEC validation\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n#                #ReportException \"${TEST_NO}\" \"Exception found, both query failed, due to connection timeout\"\n#            elif [ -z \"${GOOD}\" -a -n \"${BAD}\" ]; then\n#                LogText \"Result: good signature failed, yet bad signature was accepted\"\n#                Display --indent 4 --text \"- Checking DNSSEC validation\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n#                #ReportException \"${TEST_NO}\" \"Exception found, OK failed, bad signature was accepted\"\n#            elif [ -n \"${GOOD}\" -a -n \"${BAD}\" ]; then\n#                Display --indent 4 --text \"- Checking DNSSEC validation\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n#                LogText \"Note: Using DNSSEC validation can protect from DNS hijacking\"\n#                #ReportSuggestion \"${TEST_NO}\" \"Altered DNS queries are accepted, configure DNSSEC validating name servers\"\n#                AddHP 2 2\n#            elif [ -n \"${GOOD}\" -a -z \"${BAD}\" ]; then\n#                Display --indent 4 --text \"- Checking DNSSEC validation\" --result \"${STATUS_OK}\" --color GREEN\n#                LogText \"Result: altered DNS responses were ignored\"\n#                AddHP 0 2\n#            fi\n#        else\n#            Display --indent 4 --text \"- DNSSEC validation\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n#            LogText \"Result: dig not installed, test can't be fully performed\"\n#        fi\n#    else\n#        LogText \"Result: Test was skipped\"\n#    fi\n#\n#################################################################################\n#\n"
  },
  {
    "path": "include/tests_file_integrity",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    AIDECONFIG=\"\"\n    CSF_CONFIG=\"${ROOTDIR}etc/csf/csf.conf\"\n    FILE_INT_TOOL=\"\"\n    FILE_INT_TOOL_FOUND=0     # Boolean, file integrity tool found\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_FILE_INTEGRITY}\"\n    Display --indent 2 --text \"- Checking file integrity tools\"\n#\n#################################################################################\n#\n    # Test        : FINT-4310\n    # Description : Check if AFICK is installed\n    Register --test-no FINT-4310 --weight L --network NO --category security --description \"AFICK availability\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking AFICK binary\"\n        if [ -n \"${AFICKBINARY}\" ]; then\n            LogText \"Result: AFICK is installed (${AFICKBINARY})\"\n            Report \"file_integrity_tool[]=afick\"\n            FILE_INT_TOOL=\"afick\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- AFICK\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: AFICK is not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- AFICK\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4314\n    # Description : Check if AIDE is installed\n    Register --test-no FINT-4314 --weight L --network NO --category security --description \"AIDE availability\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking AIDE binary\"\n        if [ -n \"${AIDEBINARY}\" ]; then\n            LogText \"Result: AIDE is installed (${AIDEBINARY})\"\n            Report \"file_integrity_tool[]=aide\"\n            FILE_INT_TOOL=\"aide\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- AIDE\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: AIDE is not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- AIDE\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4315\n    # Description : Check AIDE configuration file\n    if [ -n \"${AIDEBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FINT-4315 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check AIDE configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        AIDE_CONFIG_LOCS=\"${ROOTDIR}etc ${ROOTDIR}etc/aide ${ROOTDIR}usr/local/etc\"\n        LogText \"Test: search for aide.conf in ${AIDE_CONFIG_LOCS}\"\n        for I in ${AIDE_CONFIG_LOCS}; do\n            if [ -f \"${I}/aide.conf\" ]; then\n                LogText \"Result: found aide.conf in directory ${I}\"\n                AIDECONFIG=\"${I}/aide.conf\"\n            fi\n        done\n\n        if [ -z \"${AIDECONFIG}\" ]; then\n            Display --indent 6 --text \"- AIDE config file\" --result \"${STATUS_NOT_FOUND}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"No AIDE configuration file was found, needed for AIDE functionality\"\n        else\n            LogText \"Checking configuration file ${AIDECONFIG} for errors\"\n            FIND=$(${AIDEBINARY} --config=${AIDECONFIG} -D)\n            if [ $? -eq 0 ]; then\n                Display --indent 6 --text \"- AIDE config file\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                Display --indent 6 --text \"- AIDE config file\" --result \"${STATUS_WARNING}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Check the AIDE configuration file as it may contain errors\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4316\n    # Description : Presence of AIDE database and size check\n    if [ -n \"${AIDEBINARY}\" -a -n \"${AIDECONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FINT-4316 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Presence of AIDE database and size check\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        AIDE_DB=$(${GREPBINARY} -E '(^database|^database_in)=' ${AIDECONFIG} | ${SEDBINARY} \"s/.*://\")\n        if case ${AIDE_DB} in @@*) ;; *) false;; esac; then\n            I=$(${GREPBINARY} \"@@define.*DBDIR\" ${AIDECONFIG} | ${AWKBINARY} '{print $3}')\n            AIDE_DB=$(echo ${AIDE_DB} | ${SEDBINARY} \"s#.*}#${I}#\")\n        fi\n        LogText \"Test: search for AIDE database on disk ${AIDE_DB}\"\n\n        if [ ! -e \"${AIDE_DB}\" ]; then\n            Display --indent 6 --text \"- AIDE database\" --result \"${STATUS_NOT_FOUND}\" --color RED\n            LogText \"Result: AIDE database ${AIDE_DB} does not exist\"\n            ReportWarning \"${TEST_NO}\" \"No AIDE database was found, needed for AIDE functionality\"\n        else\n            LogText \"Checking database size ${AIDE_DB}\"\n            if [ -s \"${AIDE_DB}\" ]; then\n                Display --indent 6 --text \"- AIDE database\" --result \"${STATUS_FOUND}\" --color GREEN\n                LogText \"Result: AIDE database ${AIDE_DB} exist and has a size greater than zero\"\n            else\n                Display --indent 6 --text \"- AIDE database\" --result \"${STATUS_WARNING}\" --color YELLOW\n                LogText \"Result: AIDE database ${AIDE_DB} exist but has a size of zero\"\n                ReportSuggestion \"${TEST_NO}\" \"Check the AIDE database as it may contain errors\"\n            fi\n        fi\n        unset AIDE_DB I\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4318\n    # Description : Check if Osiris is installed\n    Register --test-no FINT-4318 --weight L --network NO --category security --description \"Osiris availability\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking Osiris binary\"\n        if [ -n \"${OSIRISBINARY}\" ]; then\n            LogText \"Result: Osiris is installed (${OSIRISBINARY})\"\n            Report \"file_integrity_tool[]=osiris\"\n            FILE_INT_TOOL=\"osiris\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- Osiris\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: Osiris is not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- Osiris\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4322\n    # Description : Check if Samhain is installed\n    Register --test-no FINT-4322 --weight L --network NO --category security --description \"Samhain availability\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking Samhain binary\"\n        if [ -n \"${SAMHAINBINARY}\" ]; then\n            LogText \"Result: Samhain is installed (${SAMHAINBINARY})\"\n            Report \"file_integrity_tool[]=samhain\"\n            FILE_INT_TOOL=\"samhain\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- Samhain\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: Samhain is not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- Samhain\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4326\n    # Description : Check if Tripwire is installed\n    Register --test-no FINT-4326 --weight L --network NO --category security --description \"Tripwire availability\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking Tripwire binary\"\n        if [ -n \"${TRIPWIREBINARY}\" ]; then\n            LogText \"Result: Tripwire is installed (${TRIPWIREBINARY})\"\n            Report \"file_integrity_tool[]=tripwire\"\n            FILE_INT_TOOL=\"tripwire\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- Tripwire\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: Tripwire is not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- Tripwire\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4328\n    # Description : Check if OSSEC system integrity tool is running\n    Register --test-no FINT-4328 --weight L --network NO --category security --description \"OSSEC syscheck daemon running\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if OSSEC syscheck daemon is running\"\n        if IsRunning \"ossec-syscheckd\"; then\n            LogText \"Result: syscheck (OSSEC) active\"\n            Report \"file_integrity_tool[]=ossec\"\n            FILE_INT_TOOL=\"ossec-syscheck\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- OSSEC (syscheck)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: syscheck (OSSEC) is not active\"\n            if IsVerbose; then Display --indent 4 --text \"- OSSEC\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4330\n    # Description : Check if mtree is installed\n    # Note        : Usually on BSD and similar\n    Register --test-no FINT-4330 --weight L --network NO --category security --description \"mtree availability\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking mtree binary\"\n        if [ -n \"${MTREEBINARY}\" ]; then\n            LogText \"Result: mtree is installed (${MTREEBINARY})\"\n            Report \"file_integrity_tool[]=mtree\"\n            FILE_INT_TOOL=\"mtree\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- mtree\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: mtree is not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- mtree\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4334\n    # Description : Check if LFD is used (part of CSF suite)\n    if [ -f ${CSF_CONFIG} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FINT-4334 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check lfd daemon status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 4 --text \"- lfd (CSF)\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Test: determine lfd status\"\n        if IsRunning \"lfd - sleeping\"; then\n            LogText \"Result: lfd daemon is running (CSF)\"\n            Report \"file_integrity_tool[]=csf-lfd\"\n            Display --indent 6 --text \"- LFD (CSF) daemon\" --result \"${STATUS_RUNNING}\" --color GREEN\n            FILE_INT_TOOL=\"csf-lfd\"\n            FILE_INT_TOOL_FOUND=1\n        else\n            Display --indent 6 --text \"- LFD (CSF) daemon\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4336\n    # Description : Check if LFD is enabled (part of CSF suite)\n    if [ -f ${CSF_CONFIG} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FINT-4336 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check lfd configuration status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # LFD configuration parameters\n        ENABLED=$(${GREPBINARY} \"^LF_DAEMON = \\\"1\\\"\" ${CSF_CONFIG})\n        if [ -n \"${ENABLED}\" ]; then\n            LogText \"Result: lfd service is configured to run\"\n            Display --indent 6 --text \"- Configuration status\" --result \"${STATUS_ENABLED}\" --color GREEN\n        else\n            LogText \"Result: lfd service is configured NOT to run\"\n            Display --indent 6 --text \"- Configuration status\" --result \"${STATUS_DISABLED}\" --color YELLOW\n        fi\n        ENABLED=$(${GREPBINARY} \"^LF_DIRWATCH =\" ${CSF_CONFIG} | ${AWKBINARY} '{ print $3 }' | ${SEDBINARY} 's/\\\"//g')\n        if [ ! \"${ENABLED}\" = \"0\" -a -n \"${ENABLED}\" ]; then\n            LogText \"Result: lfd directory watching is enabled (value: ${ENABLED})\"\n            Display --indent 6 --text \"- Temporary directory watches\" --result \"${STATUS_ENABLED}\" --color GREEN\n        else\n            LogText \"Result: lfd directory watching is disabled\"\n            Display --indent 6 --text \"- Temporary directory watches\" --result \"${STATUS_DISABLED}\" --color YELLOW\n        fi\n        ENABLED=$(${GREPBINARY} \"^LF_DIRWATCH_FILE =\" ${CSF_CONFIG} | ${AWKBINARY} '{ print $3 }' | ${SEDBINARY} 's/\\\"//g')\n        if [ ! \"${ENABLED}\" = \"0\" -a -n \"${ENABLED}\" ]; then\n            Display --indent 6 --text \"- Directory/File watches\" --result \"${STATUS_ENABLED}\" --color GREEN\n        else\n            Display --indent 6 --text \"- Directory/File watches\" --result \"${STATUS_DISABLED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4338\n    # Description : Check if osquery system integrity tool is running\n    Register --test-no FINT-4338 --weight L --network NO --category security --description \"osqueryd syscheck daemon running\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if osqueryd syscheck daemon is running\"\n        if IsRunning \"osqueryd\"; then\n            LogText \"Result: syscheck (osquery) installed\"\n            Report \"file_integrity_tool[]=osquery\"\n            FILE_INT_TOOL=\"osquery\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- osquery daemon (syscheck)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: syscheck (osquery) not installed\"\n            if IsVerbose; then Display --indent 4 --text \"- osquery daemon (syscheck)\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4339\n    # Description : Check IMA/EVM status\n    if [ ! -z \"${EVMCTLBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No evmctl binary found\"; fi\n    Register --test-no FINT-4339 --os Linux --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Check IMA/EVM status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        if [ -e /sys/kernel/security/ima ]; then\n            FOUND=$(${CAT_BINARY} /sys/kernel/security/ima/runtime_measurements_count)\n        fi\n        if [ \"${FOUND}\" -ne 1 ]; then\n            LogText \"Result: EVM tools found but IMA/EVM disabled\"\n            Display --indent 2 --text \"- IMA/EVM (status)\" --result \"${STATUS_DISABLED}\" --color YELLOW\n        else\n            LogText \"Result: EVM tools found, IMA/EVM enabled\"\n            FILE_INT_TOOL=\"evmctl\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 2 --text \"- IMA/EVM (status)\" --result \"${STATUS_ENABLED}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4340\n    # Description : Check dm-integrity status\n    if [ ! -z \"${INTEGRITYSETUPBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No integritysetup binary found\"; fi\n    Register --test-no FINT-4340 --os Linux --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Check dm-integrity status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        ROOTPROTECTED=0\n\tROOTDEVICE=$(${MOUNTBINARY} | ${AWKBINARY} '/ on \\/ type / { print $1 }')\n\tfor DEVICE in /dev/mapper/*; do\n\t    if [ -e \"${DEVICE}\" ]; then\n\t\tFIND=$(${INTEGRITYSETUPBINARY} status \"${DEVICE}\" | ${GREPBINARY} -E 'type:.*INTEGRITY')\n\t\tif [ ! -z \"${FIND}\" ]; then\n\t\t    FOUND=1\n\t\t    LogText \"Result: found dm-integrity device ${DEVICE}\"\n\t\t    if [ \"${DEVICE}\" = \"${ROOTDEVICE}\" ]; then\n\t\t\tROOTPROTECTED=1\n\t\t    fi\n\t\tfi\n\t    fi\n\tdone\n        if [ \"${FOUND}\" -ne 1 ]; then\n            LogText \"Result: dm-integrity tools found but no active devices\"\n            Display --indent 2 --text \"- dm-integrity (status)\" --result \"${STATUS_DISABLED}\" --color WHITE\n        else\n            LogText \"Result: dm-integrity tools found, active devices\"\n\t    if [ ${ROOTPROTECTED} -eq 1 ]; then\n\t\tLogText \"Result: root filesystem is protected by dm-integrity\"\n\t\tDisplay --indent 2 --text \"- dm-integrity (status)\" --result \"${STATUS_ENABLED}\" --color GREEN\n\t    else\n\t\tLogText \"Result: root filesystem is not protected by dm-integrity but active devices found\"\n\t\tDisplay --indent 2 --text \"- dm-integrity (status)\" --result \"${STATUS_FOUND}\" --color YELLOW\n\t    fi\n            FILE_INT_TOOL=\"dm-integrity\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 2 --text \"- dm-integrity (status)\" --result \"${STATUS_ENABLED}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4341\n    # Description : Check dm-verity status\n    if [ ! -z \"${VERITYSETUPBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No veritysetup binary found\"; fi\n    Register --test-no FINT-4341 --os Linux --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Check dm-verity status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        ROOTPROTECTED=0\n\tROOTDEVICE=$(${MOUNTBINARY} | ${AWKBINARY} '/ on \\/ type / { print $1 }')\n\tfor DEVICE in /dev/mapper/*; do\n\t    if [ -e \"${DEVICE}\" ]; then\n\t\tFIND=$(${VERITYSETUPBINARY} status \"${DEVICE}\" | ${GREPBINARY} -E 'type:.*VERITY')\n\t\tif [ ! -z \"${FIND}\" ]; then\n\t\t    FOUND=1\n\t\t    LogText \"Result: found dm-verity device ${DEVICE}\"\n\t\t    if [ \"${DEVICE}\" = \"${ROOTDEVICE}\" ]; then\n\t\t\tROOTPROTECTED=1\n\t\t    fi\n\t\tfi\n\t    fi\n\tdone\n        if [ \"${FOUND}\" -ne 1 ]; then\n            LogText \"Result: dm-verity tools found but no active devices\"\n            Display --indent 2 --text \"- dm-verity (status)\" --result \"${STATUS_DISABLED}\" --color WHITE\n        else\n            LogText \"Result: dm-verity tools found, active devices\"\n\t    if [ ${ROOTPROTECTED} -eq 1 ]; then\n\t\tLogText \"Result: root filesystem is protected by dm-verity\"\n\t\tDisplay --indent 2 --text \"- dm-verity (status)\" --result \"${STATUS_ENABLED}\" --color GREEN\n\t    else\n\t\tLogText \"Result: root filesystem is not protected by dm-verity but active devices found\"\n\t\tDisplay --indent 2 --text \"- dm-verity (status)\" --result \"${STATUS_FOUND}\" --color YELLOW\n\t    fi\n            FILE_INT_TOOL=\"dm-verity\"\n            FILE_INT_TOOL_FOUND=1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4344\n    # Description : Check if Wazuh system integrity tool is running\n    Register --test-no FINT-4344 --weight L --network NO --category security --description \"Wazuh syscheck daemon running\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if Wazuh syscheck daemon is running\"\n        if IsRunning \"wazuh-syscheckd\"; then\n            LogText \"Result: syscheck (Wazuh) active\"\n            Report \"file_integrity_tool[]=wazuh\"\n            FILE_INT_TOOL=\"wazuh-syscheck\"\n            FILE_INT_TOOL_FOUND=1\n            Display --indent 4 --text \"- Wazuh (syscheck)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: syscheck (Wazuh) is not active\"\n            if IsVerbose; then Display --indent 4 --text \"- Wazuh\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4402 (was FINT-4316)\n    # Description : Check if AIDE is configured to use SHA256 or SHA512 checksums\n    if [ ! \"${AIDEBINARY}\" = \"\" -a -n \"${AIDECONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FINT-4402 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"AIDE configuration: Checksums (SHA256 or SHA512)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${GREPBINARY} -v \"^#\" ${AIDECONFIG} | ${GREPBINARY} -E \"= .*(sha256|sha512)\")\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: No SHA256 or SHA512 found for creating checksums\"\n            Display --indent 6 --text \"- AIDE config (Checksum)\" --result Suggestion --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Use SHA256 or SHA512 to create checksums in AIDE\"\n            AddHP 1 3\n        else\n            LogText \"Result: Found SHA256 or SHA512 found for creating checksums\"\n            Display --indent 6 --text \"- AIDE config (Checksum)\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FINT-4350\n    # Description : Check if at least one file integrity tool is installed\n    Register --test-no FINT-4350 --weight L --network NO --category security --description \"File integrity software installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check if at least on file integrity tool is available/installed\"\n        if [ ${FILE_INT_TOOL_FOUND} -eq 1 ]; then\n            LogText \"Result: found at least one file integrity tool\"\n            Display --indent 2 --text \"- Checking presence integrity tool\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 5 5\n        else\n            LogText \"Result: No file integrity tools found\"\n            Display --indent 2 --text \"- Checking presence integrity tool\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Install a file integrity tool to monitor changes to critical and sensitive files\"\n            AddHP 0 5\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_file_permissions",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n#  File permissions\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_FILE_PERMISSIONS}\"\n#\n#################################################################################\n#\n    # Test        : FILE-7524\n    # Description : Perform file permissions check\n    Register --test-no FILE-7524 --weight L --network NO --category security --description \"Perform file permissions check\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Starting file permissions check\"\n        LogText \"Test: Checking file permissions\"\n        FOUND=0\n        for PROFILE in ${PROFILES}; do\n            LogText \"Using profile ${PROFILE} for baseline.\"\n            FILES=$(${GREPBINARY} -E '^permfile=|^permdir=' ${PROFILE} | ${CUTBINARY} -d= -f2 | ${CUTBINARY} -d: -f1)\n            for F in ${FILES}; do\n                LogText \"Test: checking file/directory ${F}\"\n                if [ -f \"${F}\" ]; then\n                    PERMS=$(${GREPBINARY} '^permfile=' ${PROFILE} | ${GREPBINARY} \"=${F}:\" | ${CUTBINARY} -d: -f2)\n                    if HasCorrectFilePermissions \"${F}\" \"${PERMS}\"; then\n                        Display --indent 4 --text \"File: ${F}\" --result \"${STATUS_OK}\" --color GREEN\n                    else\n                        Display --indent 4 --text \"File: ${F}\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                        FOUND=1\n                    fi\n                elif [ -d \"${F}\" ]; then\n                    PERMS=$(${GREPBINARY} '^permdir=' ${PROFILE} | ${GREPBINARY} \"=${F}:\" | ${CUTBINARY} -d: -f2)\n                    if HasCorrectFilePermissions \"${F}\" \"${PERMS}\"; then\n                        Display --indent 4 --text \"Directory: ${F}\" --result \"${STATUS_OK}\" --color GREEN\n                    else\n                        Display --indent 4 --text \"Directory: ${F}\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                        FOUND=1\n                    fi\n                else\n                    if IsVerbose; then Display --indent 4 --text \"${F}\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n                    LogText \"Skipping file/directory ${F} as it does not exist on this system\"\n                fi\n            done\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            ReportSuggestion \"${TEST_NO}\" \"Consider restricting file permissions\" \"See screen output or log file\" \"text:Use chmod to change file permissions\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_filesystems",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# File systems\n#\n#################################################################################\n#\n    # Number of days to mark a file as old\n    TMP_OLD_DAYS=90\n    LVM_VG_USED=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_FILE_SYSTEMS}\"\n#\n#################################################################################\n#\n    # Test        : FILE-6310\n    # Description : Checking if some mount points are separated from /\n    # Goal        : Users should not be able to fill their home directory or temporary directory and creating a Denial of Service\n    Register --test-no FILE-6310 --weight L --network NO --category security --description \"Checking /tmp, /home and /var directory\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking mount points\"\n        SEPARATED_FILESYTEMS=\"/home /tmp /var\"\n        for I in ${SEPARATED_FILESYTEMS}; do\n            LogText \"Test: Checking if ${I} is mounted separately or mounted on / file system\"\n            if [ -L ${I} ]; then\n                ShowSymlinkPath ${I}\n                LogText \"Result: ${I} is a symlink. Manual check required to determine exact file system options\"\n                ReportSuggestion \"${TEST_NO}\" \"Symlinked mount point needs to be checked manually\" \"${I}\" \"\"\n                Display --indent 4 --text \"- Checking ${I} mount point\" --result SYMLINK --color WHITE\n            elif [ -d ${I} ]; then\n                LogText \"Result: directory ${I} exists\"\n                case \"${OS}\" in\n                    \"AIX\") FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($2==MP) { print $2 }}') ;;\n                    \"HP-UX\") FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($1==MP) { print $1 }}') ;;\n                    *) FIND=$(${MOUNTBINARY} | ${AWKBINARY} -v MP=${I} '{ if ($3==MP) { print $3 }}') ;;\n                esac\n\n                if IsEmpty \"${FIND}\"; then\n                    LogText \"Result: ${I} not found in mount list. Directory most likely stored on / file system\"\n                    Display --indent 4 --text \"- Checking ${I} mount point\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    ReportSuggestion \"${TEST_NO}\" \"To decrease the impact of a full ${I} file system, place ${I} on a separate partition\"\n                    AddHP 9 10\n                else\n                    LogText \"Result: found ${I} as a separated mount point\"\n                    Display --indent 4 --text \"- Checking ${I} mount point\" --result \"${STATUS_OK}\" --color GREEN\n                    AddHP 10 10\n                fi\n            else\n                LogText \"Result: directory ${I} does not exist\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6311\n    # Description : Checking LVM Volume Groups\n    # Notes       : No volume groups found is sent to STDERR for unclear reasons. Filtering both STDERR redirecting and grep.\n    if [ ! \"${VGDISPLAYBINARY}\" = \"\" -o ! \"${LSVGBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6311 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking LVM volume groups\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for LVM volume groups\"\n        case ${OS} in\n            AIX)\n                 FIND=$(${LSVGBINARY} -o)\n            ;;\n            Linux)\n                 FIND=$(${VGDISPLAYBINARY} 2> /dev/null | ${GREPBINARY} -v \"No volume groups found\" | ${GREPBINARY} \"VG Name\" | ${AWKBINARY} '{ print $3 }' | ${SORTBINARY})\n            ;;\n            *)\n                 ReportException \"${TEST_NO}:1\" \"Don't know this specific operating system yet, while volume group manager was found\"\n            ;;\n        esac\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found one or more volume groups\"\n            for I in ${FIND}; do\n                LogText \"Found LVM volume group: ${I}\"\n                Report \"lvm_volume_group[]=${I}\"\n            done\n            LVM_VG_USED=1\n            Display --indent 2 --text \"- Checking LVM volume groups\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: no LVM volume groups found\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking LVM volume groups\" --result \"${STATUS_NONE}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6312\n    # Description : Checking LVM volumes\n    if [ ${LVM_VG_USED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6312 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking LVM volumes\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for LVM volumes\"\n        case ${OS} in\n            AIX)\n                 ACTIVE_VG_LIST=$(${LSVGBINARY} -o)\n                 FIND=$(for I in ${ACTIVE_VG_LIST}; do ${LSVGBINARY} -l ${I} | ${AWKBINARY} 'NR>2 { print $1 }'; done)\n            ;;\n            Linux)\n                 FIND=$(${LVDISPLAYBINARY} | ${GREPBINARY} -v \"No volume groups found\" | ${GREPBINARY} \"LV Name\" | ${AWKBINARY} '{ print $3 }' | ${SORTBINARY})\n            ;;\n            *)\n                 ReportException \"${TEST_NO}:1\" \"Need specific test for gathering volume manager data\"\n            ;;\n        esac\n        if [ ! \"${FIND}\" = \"\" ]; then\n            LogText \"Result: found one or more volumes\"\n            for I in ${FIND}; do\n                LogText \"Found LVM volume: ${I}\"\n                Report \"lvm_volume[]=${I}\"\n            done\n            Display --indent 4 --text \"- Checking LVM volumes\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: no LVM volume groups found\"\n            Display --indent 4 --text \"- Checking LVM volumes\" --result \"${STATUS_NONE}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6316\n    # Description : Checking /etc/fstab file permissions\n    #Register --test-no FILE-6316 --os Linux --weight L --network NO --category security --description \"Checking /etc/fstab\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    # 644\n#\n#################################################################################\n#\n    # Test        : FILE-6323\n    # Description : Checking Linux EXT2, EXT3, EXT4 file systems\n    Register --test-no FILE-6323 --os Linux --weight L --network NO --category security --description \"Checking EXT file systems\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for Linux EXT file systems\"\n        FIND=$(${MOUNTBINARY} -t ext2,ext3,ext4 | ${AWKBINARY} '{ print $3\",\"$5 }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found one or more EXT file systems\"\n            for I in ${FIND}; do\n                FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d ',' -f1)\n                FILETYPE=$(echo ${I} | ${CUTBINARY} -d ',' -f2)\n                LogText \"File system: ${FILESYSTEM} (type: ${FILETYPE})\"\n                Report \"file_systems_ext[]=${FILESYSTEM}|${FILETYPE}|\"\n            done\n        else\n            LogText \"Result: no EXT file systems found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6324\n    # Description : Checking Linux XFS file systems\n    Register --test-no FILE-6324 --os Linux --weight L --network NO --category security --description \"Checking XFS file systems\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for Linux XFS file systems\"\n        FIND=$(${MOUNTBINARY} -t xfs | ${AWKBINARY} '{ print $3\",\"$5 }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found one or more XFS file systems\"\n            for I in ${FIND}; do\n                FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d ',' -f1)\n                FILETYPE=$(echo ${I} | ${CUTBINARY} -d ',' -f2)\n                LogText \"File system: ${FILESYSTEM} (type: ${FILETYPE})\"\n                Report \"file_systems_xfs[]=${FILESYSTEM}|${FILETYPE}|\"\n            done\n        else\n            LogText \"Result: no XFS file systems found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6329\n    # Description : Query all FFS/UFS mounts from /etc/fstab\n    if [ -f /etc/fstab ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6329 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking FFS/UFS file systems\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Query /etc/fstab for available FFS/UFS mount points\"\n        FIND=$(${AWKBINARY} '{ if ($3 == \"ufs\" || $3 == \"ffs\" ) { print $1\":\"$2\":\"$3\":\"$4\":\" }}' /etc/fstab)\n        if [ -z \"${FIND}\" ]; then\n            if IsVerbose; then Display --indent 2 --text \"- Querying FFS/UFS mount points (fstab)\" --result \"${STATUS_NONE}\" --color WHITE; fi\n            LogText \"Result: unable to find any single mount point (FFS/UFS)\"\n        else\n            Display --indent 2 --text \"- Querying FFS/UFS mount points (fstab)\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"filesystem[]=ufs\"\n            for I in ${FIND}; do\n                LogText \"FFS/UFS mount found: ${I}\"\n                Report \"mountpoint_ufs[]=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6330\n    # Description : Query ZFS mounts\n    # Note        : mount -p does not work under Linux\n    Register --test-no FILE-6330 --os FreeBSD --weight L --network NO --category security --description \"Checking ZFS file systems\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Discover for available ZFS mount points\"\n        FIND=$(${MOUNTBINARY} -p | ${AWKBINARY} '{ if ($3 == \"zfs\") { print $1\":\"$2\":\"$3\":\"$4\":\" }}')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Querying ZFS mount points (mount -p)\" --result \"${STATUS_NONE}\" --color WHITE\n            LogText \"Result: unable to find any single mount point (ZFS)\"\n        else\n            Display --indent 2 --text \"- Querying ZFS mount points (mount -p)\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"filesystem[]=zfs\"\n            for I in ${FIND}; do\n                LogText \"ZFS mount found: ${I}\"\n                Report \"mountpoint_zfs[]=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6439\n    # Description : Query all HAMMER PFS mounts from /etc/fstab\n    Register --test-no FILE-6439 --os DragonFly --weight L --network NO --category security --description \"Checking HAMMER PFS mounts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Query /etc/fstab for available HAMMER PFS mount points\"\n        FIND=$(${MOUNTBINARY} -p | ${AWKBINARY} '{ if ($3 == \"null\") { print $1\":\"$2\":\"$3\":\"$4\":\" }}')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Querying HAMMER PFS mount points (mount -p)\" --result \"${STATUS_NONE}\" --color WHITE\n            LogText \"Result: unable to find any single PFS mount point\"\n        else\n            Display --indent 2 --text \"- Querying HAMMER PFS mount points (mount -p)\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"filesystem[]=hammer\"\n            for I in ${FIND}; do\n                LogText \"HAMMER mount found: ${I}\"\n                Report \"mountpoint_hammer[]=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6332\n    # Description : Check swap partitions\n    if [ -f /etc/fstab ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6332 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking swap partitions\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: query swap partitions from /etc/fstab file\"\n        # Check if third field contains 'swap'\n        FIND=$(${AWKBINARY} '{ if ($2==\"swap\" || $3==\"swap\") { print $1 }}' /etc/fstab | ${GREPBINARY} -v \"^#\")\n        for I in ${FIND}; do\n            FOUND=1\n            REAL=\"\"\n            UUID=\"\"\n            LogText \"Swap partition found: ${I}\"\n            # TODO Add a test if partition is not a normal partition (e.g. UUID=)\n            # Can be ^/dev/mapper/vg-name_lv-name\n            # Can be ^/dev/partition\n\n            # Test for UUID usage (e.g. UUID=uuid --> /dev/disk/by-uuid/<uuid>)\n            HAS_UUID=$(echo ${I} | ${GREPBINARY} \"^UUID=\")\n            if [ -n \"${HAS_UUID}\" ]; then\n                UUID=$(echo ${HAS_UUID} | ${AWKBINARY} -F= '{ print $2 }')\n                LogText \"Result: Using ${UUID} as UUID\"\n                if [ -n \"${BLKIDBINARY}\" ]; then\n                    FIND2=$(${BLKIDBINARY} | ${AWKBINARY} '{ if ($2==\"UUID=\\\"${UUID}\\\"\") print $1 }' | ${SEDBINARY} 's/:$//')\n                    if [ -n \"${FIND2}\" ]; then\n                        REAL=\"${FIND2}\"\n                    fi\n                else\n                    LogText \"Result: blkid binary not found, trying by checking device listing\"\n                    sFILE=\"\"\n                    if [ -L /dev/disk/by-uuid/${UUID} ]; then\n                        LogText \"Result: found disk via /dev/disk/by-uuid listing\"\n                        ShowSymlinkPath /dev/disk/by-uuid/${UUID}\n                        if [ -n \"${sFILE}\" ]; then\n                            REAL=\"${sFILE}\"\n                            LogText \"Result: disk is ${REAL}\"\n                        fi\n                    else\n                        LogText \"Result: no symlink found to /dev/disk/by-uuid/${UUID}\"\n                    fi\n                fi\n            fi\n            # Set real device\n            if [ -z \"${REAL}\" ]; then\n                REAL=\"${I}\"\n            fi\n            Report \"swap_partition[]=${I},${REAL},\"\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Query swap partitions (fstab)\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Query swap partitions (fstab)\" --result \"${STATUS_NONE}\" --color YELLOW\n            LogText \"Result: no swap partitions found in /etc/fstab\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6336\n    # Description : Check swap mount options\n    # Examples    : [partition] swap swap defaults 0 0\n    #               [partition] none swap sw 0 0\n    if [ -f /etc/fstab ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6336 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking swap mount options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Swap partitions should be mounted with 'sw' or 'swap'\n        LogText \"Test: check swap partitions with incorrect mount options\"\n        FIND=$(${AWKBINARY} '{ if ($3==\"swap\" && ($4!~/sw/ && $4!=\"defaults\")) { print $1 }}' /etc/fstab)\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Testing swap partitions\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: all swap partitions have correct options (sw or swap)\"\n        else\n            Display --indent 2 --text \"- Testing swap partitions\" --result \"${STATUS_CHECK_NEEDED}\" --color YELLOW\n            LogText \"Result: possible incorrect mount options used for mounting swap partition (${FIND})\"\n            #ReportWarning \"${TEST_NO}\" \"Possible incorrect mount options used for swap partition (${FIND})\"\n            ReportSuggestion \"${TEST_NO}\" \"Check your /etc/fstab file for swap partition mount options\"\n            LogText \"Notes: usually swap partition have 'sw' or 'swap' in the options field (4th)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6344\n    # Description : Check proc mount options (Linux >=3.3 only)\n    #               hidepid textual values available kernel >= 5.8 only)\n    # Examples    : proc /proc proc defaults,hidepid=2 0 0\n    # Goal        : Users should not be able to see processes of other users\n    if [ \"${OS}\" = \"Linux\" -a -f ${ROOTDIR}proc/version ]; then\n        LINUX_KERNEL_MAJOR=$(echo $OS_KERNELVERSION | ${AWKBINARY} -F. '{print $1}')\n        LINUX_KERNEL_MINOR=$(echo $OS_KERNELVERSION | ${AWKBINARY} -F. '{print $2}')\n        if [ -n \"${LINUX_KERNEL_MAJOR}\" -a -n \"${LINUX_KERNEL_MINOR}\" ]; then\n            if [ ${LINUX_KERNEL_MAJOR} -ge 3 -a ${LINUX_KERNEL_MINOR} -ge 3 ]; then\n                PREQS_MET=\"YES\";\n            elif [ ${LINUX_KERNEL_MAJOR} -ge 4 ]; then\n                PREQS_MET=\"YES\";\n            else\n                PREQS_MET=\"NO\";\n            fi\n        else\n            PREQS_MET=\"NO\";\n        fi\n    fi\n    Register --test-no FILE-6344 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking proc mount options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Proc should be mounted with 'hidepid=2' or 'hidepid=1' at least\n        # https://www.kernel.org/doc/html/latest/filesystems/proc.html#chapter-4-configuring-procfs\n        LogText \"Test: check proc mount with incorrect mount options\"\n        FIND=$(${MOUNTBINARY} | ${GREPBINARY} -E \"${ROOTDIR}proc \" | ${GREPBINARY} -E -o \"hidepid=([0-9]|[a-z][a-z]*)\")\n        if [ \"${FIND}\" = \"hidepid=4\" -o \"${FIND}\" = \"hidepid=ptraceable\" ]; then  # https://lwn.net/Articles/817137/\n            Display --indent 2 --text \"- Testing /proc mount (hidepid)\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: proc mount mounted with ${FIND}\"\n            AddHP 3 3\n        elif [ \"${FIND}\" = \"hidepid=2\" -o \"${FIND}\" = \"hidepid=invisible\" ]; then\n            Display --indent 2 --text \"- Testing /proc mount (hidepid)\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: proc mount mounted with ${FIND}\"\n            AddHP 3 3\n        elif [ \"${FIND}\" = \"hidepid=1\" -o \"${FIND}\" = \"hidepid=noaccess\" ]; then\n            Display --indent 2 --text \"- Testing /proc mount (hidepid)\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: proc mount mounted with ${FIND}\"\n            AddHP 2 3\n        elif [ -z \"${FIND}\" ]; then\n            # HIDEPID1_SUGGESTION=\" (or at least hidepid=1)\"\n            AddHP 0 3\n            Display --indent 2 --text \"- Testing /proc mount (hidepid)\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: /proc filesystem is not mounted with option hidepid=1 or hidepid=2\"\n            # TODO ReportSuggestion \"${TEST_NO}\" \"Consider mounting /proc via /etc/fstab with mount option hidepid=2\" \"/proc\" \"-\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6354\n    # Description : Search files within /tmp which are older than 3 months\n    if [ -d ${ROOTDIR}tmp ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6354 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Searching for old files in /tmp\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for old files in ${ROOTDIR}tmp\"\n        # Search for files only in ${ROOTDIR}tmp, with an access time older than X days\n        FIND=$(${FINDBINARY} ${ROOTDIR}tmp -xdev -type f -atime +${TMP_OLD_DAYS} 2> /dev/null | ${SEDBINARY} 's/ /!space!/g')\n        if IsEmpty \"${FIND}\"; then\n            Display --indent 2 --text \"- Checking for old files in ${ROOTDIR}tmp\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: no files found in ${ROOTDIR}tmp which are older than 3 months\"\n        else\n            Display --indent 2 --text \"- Checking for old files in ${ROOTDIR}tmp\" --result \"${STATUS_FOUND}\" --color RED\n            COUNT=0\n            for ITEM in ${FIND}; do\n                FILE=$(echo ${ITEM} | ${SEDBINARY} 's/!space!/ /g')\n                LogText \"Old temporary file: ${FILE}\"\n                COUNT=$((COUNT + 1))\n            done\n            LogText \"Result: found old files in ${ROOTDIR}tmp, which were not modified in the last ${TMP_OLD_DAYS} days\"\n            LogText \"Advice: check and clean up unused files in ${ROOTDIR}tmp. Old files can fill up a disk or contain\"\n            LogText \"private information and should be deleted it not being used actively. Use a tool like lsof to\"\n            LogText \"see which programs possibly are using a particular file. Some systems can cleanup temporary\"\n            LogText \"directories by setting a boot option.\"\n            ReportSuggestion \"${TEST_NO}\" \"Check ${COUNT} files in ${ROOTDIR}tmp which are older than ${TMP_OLD_DAYS} days\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6362\n    # Description : Check for sticky bit on /tmp\n    if [ -d ${ROOTDIR}tmp -a ! -L ${ROOTDIR}tmp ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No /tmp or /tmp is symlinked\"; fi\n    Register --test-no FILE-6362 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Checking /tmp sticky bit\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Depending on OS, number of field with 'tmp' differs\n        FIND=$(${LSBINARY} -ld ${ROOTDIR}tmp | ${AWKBINARY} '$1 ~ /[tT]/ { print 1 }')\n        if [ \"${FIND}\" = \"1\" ]; then\n            Display --indent 2 --text \"- Checking ${ROOTDIR}tmp sticky bit\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: sticky bit found on ${ROOTDIR}tmp directory\"\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- Checking ${ROOTDIR}tmp sticky bit\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Set the sticky bit on ${ROOTDIR}tmp, to prevent users deleting (by other owned) files in the /tmp directory.\" \"/tmp\" \"text:Set sticky bit\"\n            AddHP 0 3\n        fi\n        unset FIND\n    else\n        LogText \"Result: Sticky bit test (on /tmp) skipped. Possible reason: missing directory, or symlinked directory, or test skipped.\"\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6363\n    # Description : Check for sticky bit on /var/tmp\n    if [ -d ${ROOTDIR}var/tmp -a ! -L ${ROOTDIR}var/tmp ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No /var/tmp or /var/tmp is symlinked\"; fi\n    Register --test-no FILE-6363 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Checking /var/tmp sticky bit\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Depending on OS, number of field with 'tmp' differs\n        FIND=$(${LSBINARY} -ld ${ROOTDIR}var/tmp | ${AWKBINARY} '$1 ~ /[tT]/ { print 1 }')\n        if [ \"${FIND}\" = \"1\" ]; then\n            Display --indent 2 --text \"- Checking ${ROOTDIR}var/tmp sticky bit\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: sticky bit found on ${ROOTDIR}var/tmp directory\"\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- Checking ${ROOTDIR}var/tmp sticky bit\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Set the sticky bit on ${ROOTDIR}var/tmp, to prevent users deleting (by other owned) files in the /var/tmp directory.\" \"/var/tmp\" \"text:Set sticky bit\"\n            AddHP 0 3\n        fi\n        unset FIND\n    else\n        LogText \"Result: Sticky bit test (on /var/tmp) skipped. Possible reason: missing directory, or symlinked directory, or test skipped.\"\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6366\n    # Description : Check for noatime option\n    # More info   : especially useful for profile 'desktop' and 'server-storage'\n\n    # Want to contribute to Lynis? Create this test\n\n#\n#################################################################################\n#\n    # Test        : FILE-6368\n    # Description : Checking Linux root file system ACL support\n    Register --test-no FILE-6368 --os Linux --weight L --network NO --root-only YES --category security --description \"Checking ACL support on root file system\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: Checking acl option on ext[2-4] root file system\"\n        FIND=$(${MOUNTBINARY} | ${AWKBINARY} '{ if ($3==\"/\" && $5~/ext[2-4]/) { print $6 } }' | ${GREPBINARY} acl)\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found ACL option\"\n            FOUND=1\n        else\n            LogText \"Result: mount point probably mounted with defaults\"\n            LogText \"Test: Checking device which holds root file system\"\n            # Get device on which root file system is mounted. Use /dev/root if it exists, or\n            # else check output of mount\n            if [ -b ${ROOTDIR}dev/root ]; then\n                FIND1=\"${ROOTDIR}dev/root\"\n            else\n                # Only determine device if it is EXT2/3/4\n                #FIND1=$(mount | ${GREPBINARY} \"on / \" | ${AWKBINARY} '{ if ($5~/ext[2-4]/) { print $1 }}')\n                FIND1=$(${MOUNTBINARY} -t ext2,ext3,ext4 | ${GREPBINARY} \"on / \" | ${AWKBINARY} '{ print $1 }')\n            fi\n            # Trying to determine default mount options from EXT2/EXT3/EXT4 file systems\n            if [ -n \"${FIND1}\" ]; then\n                LogText \"Result: found ${FIND1}\"\n                LogText \"Test: Checking default options on ${FIND1}\"\n                FIND2=$(${TUNE2FSBINARY} -l ${FIND1} 2> /dev/null | ${GREPBINARY} \"^Default mount options\" | ${GREPBINARY} \"acl\")\n                if [ -n \"${FIND2}\" ]; then\n                    LogText \"Result: found ACL option in default mount options\"\n                    FOUND=1\n                else\n                    LogText \"Result: no ACL option found in default mount options list\"\n                fi\n            else\n                LogText \"Result: No file system found with root file system\"\n            fi\n        fi\n\n        LogText \"Test: Checking acl option on xfs root file system\"\n        FIND=$(${MOUNTBINARY} | ${AWKBINARY} '{ if ($3==\"/\" && $5~/xfs/) { print $6 } }' | ${GREPBINARY} -E 'no_acl|no_user_xattr')\n        if [ -z \"${FIND}\" ]; then\n            FOUND=1\n            # some other tests to do ?\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: ACL option NOT enabled on root file system\"\n            LogText \"Additional information: if file access need to be more restricted, ACLs could be used. Install the acl utilities and remount the file system with the acl option\"\n            LogText \"Activate acl support on and active file system with mount -o remount,acl / and add the acl option to the fstab file\"\n            Display --indent 2 --text \"- ACL support root file system\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            AddHP 0 1\n        else\n            LogText \"Result: ACL option enabled on root file system\"\n            Display --indent 2 --text \"- ACL support root file system\" --result \"${STATUS_ENABLED}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6372\n    # Description : Check / mount options for Linux\n    # Notes       :\n    Register --test-no FILE-6372 --os Linux --weight L --network NO --category security --description \"Checking / mount options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}etc/fstab ]; then\n            FIND=$(${GREPBINARY} -w \"/\" ${ROOTDIR}etc/fstab | ${GREPBINARY} -v \"^#\" | ${CUTBINARY} -f1 -d\"#\" | ${AWKBINARY} '{ if ($2==\"/\") { print $4 }}')\n            NODEV=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ \"nodev\") { print \"YES\" } else { print \"NO\" } }')\n            NOEXEC=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ \"noexec\") { print \"YES\" } else { print \"NO\" } }')\n            NOSUID=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ \"nosuid\") { print \"YES\" } else { print \"NO\" } }')\n\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: mount system / is configured with options: ${FIND}\"\n                if [ \"${FIND}\" = \"defaults\" ]; then\n                    Display --indent 2 --text \"- Mount options of /\" --result \"${STATUS_OK}\" --color GREEN\n                else\n                    Display --indent 2 --text \"- Mount options of /\" --result \"${STATUS_NON_DEFAULT}\" --color YELLOW\n                fi\n            else\n                LogText \"Result: no mount point / or expected options found\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6374\n    # Description : Check mount options for Linux\n    # Notes       : This test determines if the mount point exists. If it does not exist as mount point, yet it is an directory,\n    #               you might consider to make it a separate mount point with restrictions.\n    #\n    #               Depending on the primary goals of a machine, some mount points might be too restrictive. Before applying any\n    #               mount flags, test them on a similar or cloned test system.\n    #\n    #            ---------------------------------------------------------\n    #               Mount point              nodev  noexec  nosuid\n    #               /boot                      v      v       v\n    #               /dev                              v       v\n    #               /dev/shm                   v      v       v\n    #               /home                      v              v\n    #               /run                       v              v\n    #               /tmp                       v      v       v\n    #               /var                       v              v\n    #               /var/log                   v      v       v\n    #               /var/log/audit             v      v       v\n    #               /var/tmp                   v      v       v\n    #            ---------------------------------------------------------\n\n    FILESYSTEMS_TO_CHECK=\"/boot:nodev,noexec,nosuid /dev:noexec,nosuid /dev/shm:nosuid,nodev,noexec /home:nodev,nosuid /run:nodev,nosuid /tmp:nodev,noexec,nosuid /var:nodev,nosuid /var/log:nodev,noexec,nosuid /var/log/audit:nodev,noexec,nosuid /var/tmp:nodev,noexec,nosuid\"\n    Register --test-no FILE-6374 --os Linux --weight L --network NO --category security --description \"Linux mount options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}etc/fstab ]; then\n            for I in ${FILESYSTEMS_TO_CHECK}; do\n                FILESYSTEM=$(echo ${I} | ${CUTBINARY} -d: -f1)\n                EXPECTED_FLAGS=$(echo ${I} | ${CUTBINARY} -d: -f2 | ${SEDBINARY} 's/,/ /g')\n                FS_FSTAB=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($2==fs) { print $3 } }' ${ROOTDIR}etc/fstab)\n                if [ \"${FS_FSTAB}\" = \"glusterfs\" ]; then\n                    EXPECTED_FLAGS=$(echo ${EXPECTED_FLAGS} | ${SEDBINARY} 's/\\<\\(nodev\\|nosuid\\)\\> *//g')\n                    if [ -z \"${EXPECTED_FLAGS}\" ]; then\n                        FS_FSTAB=\"\"\n                    fi\n                fi\n                if [ -z \"${FS_FSTAB}\" ]; then # not found in fstab, check if mounted otherwise\n                    FS_FSTAB=$(mount | ${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($3==fs) { print $6 } }')\n                    FOUND_FLAGS=$(mount | ${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($1~\"[^#]\" && $3==fs) { print $6 } }' | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\\n' ' ')\n                else\n                    FOUND_FLAGS=$(${AWKBINARY} -v fs=${FILESYSTEM} '{ if ($1~\"[^#]\" && $2==fs) { print $4 } }' ${ROOTDIR}etc/fstab | ${SEDBINARY} 's/,/ /g' | ${TRBINARY} '\\n' ' ')\n                fi\n                if [ -n \"${FS_FSTAB}\" ]; then\n                    # In awk using caret/circumflex as first character between brackets, means 'not' (instead of beginning of line)\n                    LogText \"File system:    ${FILESYSTEM}\"\n                    LogText \"Expected flags: ${EXPECTED_FLAGS}\"\n                    LogText \"Found flags:    ${FOUND_FLAGS}\"\n                    PARTIALLY_HARDENED=0\n                    FULLY_HARDENED=1\n                    for FLAG in ${EXPECTED_FLAGS}; do\n                        FLAG_AVAILABLE=$(echo ${FOUND_FLAGS} | ${GREPBINARY} ${FLAG})\n                        if [ -z \"${FLAG_AVAILABLE}\" ]; then\n                            LogText \"Result: Could not find mount option ${FLAG} on file system ${FILESYSTEM}\"\n                            FULLY_HARDENED=0\n                        else\n                            LogText \"Result: GOOD, found mount option ${FLAG} on file system ${FILESYSTEM}\"\n                            PARTIALLY_HARDENED=1\n                        fi\n                    done\n                    if [ ${FULLY_HARDENED} -eq 1 ]; then\n                        LogText \"Result: marked ${FILESYSTEM} as fully hardened\"\n                        Display --indent 2 --text \"- Mount options of ${FILESYSTEM}\" --result \"${STATUS_HARDENED}\" --color GREEN\n                        AddHP 5 5\n                    elif [ ${PARTIALLY_HARDENED} -eq 1 ]; then\n                        LogText \"Result: marked ${FILESYSTEM} as partially hardened\"\n                        Display --indent 2 --text \"- Mount options of ${FILESYSTEM}\" --result \"${STATUS_PARTIALLY_HARDENED}\" --color YELLOW\n                        AddHP 4 5\n                    else\n                        if ContainsString \"defaults\" \"${FOUND_FLAGS}\"; then\n                            LogText \"Result: marked ${FILESYSTEM} options as default (not hardened)\"\n                            Display --indent 2 --text \"- Mount options of ${FILESYSTEM}\" --result \"${STATUS_DEFAULT}\" --color YELLOW\n                            AddHP 3 5\n                        else\n                            LogText \"Result: marked ${FILESYSTEM} options as non-default (unclear about hardening)\"\n                            Display --indent 2 --text \"- Mount options of ${FILESYSTEM}\" --result \"${STATUS_NON_DEFAULT}\" --color YELLOW\n                            AddHP 4 5\n                        fi\n                    fi\n                else\n                    LogText \"Result: file system ${FILESYSTEM} not found in ${ROOTDIR}etc/fstab\"\n                fi\n            done\n        fi\n        NMOUNTS=$(mount | ${WCBINARY} -l)\n        NDEVMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v nodev | ${WCBINARY} -l)\n        NEXECMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v noexec | ${WCBINARY} -l)\n        NSUIDMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v nosuid | ${WCBINARY} -l)\n        NWRITEANDEXECMOUNTS=$(mount | ${AWKBINARY} '{print $6}' | ${GREPBINARY} -v noexec | ${GREPBINARY} -E -v '^\\(ro[,)]' | ${WCBINARY} -l)\n        LogText \"Result: Total without nodev:${NDEVMOUNTS} noexec:${NEXECMOUNTS} nosuid:${NSUIDMOUNTS} ro or noexec (W^X): ${NWRITEANDEXECMOUNTS}, of total ${NMOUNTS}\"\n        Display --indent 2 --text \"- Total without nodev:${NDEVMOUNTS} noexec:${NEXECMOUNTS} nosuid:${NSUIDMOUNTS} ro or noexec (W^X): ${NWRITEANDEXECMOUNTS} of total ${NMOUNTS}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6376\n    # Description : Bind mount the /var/tmp directory to /tmp\n    Register --test-no FILE-6376 --os Linux --weight L --network NO --category security --description \"Determine if /var/tmp is bound to /tmp\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}etc/fstab ]; then\n            FIND=$(${AWKBINARY} '{ if ($2==\"/var/tmp\") { print $4 } }' ${ROOTDIR}etc/fstab)\n            BIND=$(echo ${FIND} | ${AWKBINARY} '{ if ($1 ~ \"bind\") { print \"YES\" } else { print \"NO\" } }')\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: mount system /var/tmp is configured with options: ${FIND}\"\n                if [ \"${BIND}\" = \"YES\" ]; then\n                    Display --indent 2 --text \"- /var/tmp is bound to /tmp\" --result \"${STATUS_OK}\" --color GREEN\n                    LogText \"Result : /var/tmp is bind to /tmp\"\n                else\n                    Display --indent 2 --text \"- /var/tmp is not bound to /tmp\" --result \"${STATUS_NON_DEFAULT}\" --color YELLOW\n                    LogText \"Result: /var/tmp is not bind to /tmp\"\n                fi\n            else\n                LogText \"Result: no mount point /var/tmp or expected options found\"\n                if IsVerbose; then Display --indent 2 --text \"- /var/tmp is not bound to /tmp\" --result \"INFO\" --color WHITE; fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6378 TODO\n    # Description : Check for nodirtime option\n\n    # Want to contribute to Lynis? Create this test\n#\n#################################################################################\n#\n    # Test        : FILE-6380 TODO\n    # Description : Check for relatime\n\n    # Want to contribute to Lynis? Create this test\n#\n#################################################################################\n#\n    # Test        : FILE-6390 TODO\n    # Description : Check writeback/journalling mode (ext3)\n    # More info   : data=writeback | data=ordered | data=journal\n\n    # Want to contribute to Lynis? Create this test\n\n#\n#################################################################################\n#\n    # Test        : FILE-6394\n    # Description : Check vm.swappiness (Linux)\n    Register --test-no FILE-6394 --os Linux --weight L --network NO --category security --description \"Determine level of swappiness.\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        SWAPLEVEL=$(${CAT_BINARY} /proc/sys/vm/swappiness)\n        LogText \"Test: checking level of vm.swappiness: ${SWAPLEVEL}\"\n        PHYSDISK=$(${LSBLKBINARY} | ${GREPBINARY} -E 'disk|SWAP' | ${GREPBINARY} -B1 SWAP | ${HEADBINARY} -n1 | ${AWKBINARY} '{print $1}')\n        if [ ${SWAPLEVEL} -gt 60 ]; then\n            LogText \"Result: vm.swappiness=${SWAPLEVEL} meaning that swapping is more frequent than default.\"\n            # Check if swap is on a HDD or SDD for frequent swapping\n            if [ -d \"/sys/block/${PHYSDISK}\" ]; then\n                HDDORSDD=$(${CAT_BINARY} \"/sys/block/${PHYSDISK}/queue/rotational\")\n                if [ ${HDDORSDD} -eq 1 ]; then\n                    ReportSuggestion \"${TEST_NO}\" \"vm.swappiness set to: ${SWAPLEVEL} > 60 (default) - consider installing an SSD for swap partition for better performance.\"\n                fi\n            fi\n        elif [ ${SWAPLEVEL} -eq 0 ]; then\n            LogText \"Result: vm.swappiness=${SWAPLEVEL} meaning swapping is disabled.\"\n            ReportSuggestion \"${TEST_NO}\" \"vm.swappiness set to: ${SWAPLEVEL}. Consider setting value to minimum of 1 for minimizing swappiness, but not quite disabling it. Will prevent OOM killer from killing processes when running out of physical memory.\"\n        elif [ ${SWAPLEVEL} -eq 1 ]; then\n            LogText \"Result: vm.swappiness=${SWAPLEVEL} meaning that swapping can still occur but at very minimum.\"\n        elif [ ${SWAPLEVEL} -eq 10 ]; then\n            LogText \"Result: vm.swappiness=${SWAPLEVEL} which is the preferred setting for database servers.\"\n        elif [ ${SWAPLEVEL} -lt 60 ]; then\n            LogText \"Result: vm.swappiness=${SWAPLEVEL} meaning that swapping is less frequent than default. This is only recommended for servers.\"\n        else\n            LogText \"Result: vm.swappiness=${SWAPLEVEL} which is the standard level of swappiness and works well for desktop systems.\"\n        fi\n        if IsVerbose; then Display --indent 2 --text \"- Swappiness: ${SWAPLEVEL}\" --result \"INFO\" --color WHITE; fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6398\n    # Description : Check if JBD (Journal Block Device) driver is loaded\n    # Notes       : Test is temporarily disabled, as JBD might be in a kernel (built-in) - https://github.com/CISOfy/lynis/issues/1508\n#    Register --test-no FILE-6398 --os Linux --weight L --network NO --category security --description \"Checking if JBD (Journal Block Device) driver is loaded\"\n#    if [ ${SKIPTEST} -eq 0 ]; then\n#        LogText \"Test: Checking if JBD (Journal Block Device) driver is loaded\"\n#        NOTINUSE=0\n#        # Only perform testing if we know that KRNL-5723 performed tests\n#        if [ ${MONOLITHIC_KERNEL_TESTED} -eq 1 ]; then\n#            # Cannot check if driver is loaded/present if kernel is monolithic\n#            if [ ${MONOLITHIC_KERNEL} -eq 0 ]; then\n#                JBD=$(${LSMODBINARY} | ${GREPBINARY} ^jbd)\n#                if [ -n \"${JBD}\" ]; then\n#                    LogText \"Result: JBD driver is loaded\"\n#                    INUSE=$(echo ${JBD} | ${AWKBINARY} '{if ($3 -ne 0) {print $4}}')\n#                    if [ -n \"${INUSE}\" ]; then\n#                        LogText \"Result: JBD driver is in use by drivers: ${INUSE}\"\n#                        Report \"JBD driver is in use by drivers: ${INUSE}\"\n#                        Display --indent 2 --text \"- JBD driver loaded and in use\" --result \"${STATUS_OK}\" --color GREEN\n#                    else\n#                        NOTINUSE=1\n#                        LogText \"Result: JBD driver loaded, but not in use\"\n#                        Report \"JBD driver is loaded, but not in use.\"\n#                        Display --indent 2 --text \"- JBD driver loaded, but not in use\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n#                    fi\n#                else\n#                    NOTINUSE=2\n#                    LogText \"Result: JBD driver not loaded\"\n#                    Report \"JBD driver not loaded.\"\n#                    Display --indent 2 --text \"- JBD driver is not loaded\" --result \"${STATUS_CHECK_NEEDED}\" --color YELLOW\n#                fi\n#                if [ ${NOTINUSE} -eq 1 ]; then\n#                    ReportSuggestion \"${TEST_NO}\" \"The JBD (Journal Block Device) driver is loaded but not in use.\" \"You are currently not using any filesystems with journaling, i.e. you have greater risk of data corruption in case of system crash.\"\n#                elif [ ${NOTINUSE} -eq 2 ]; then\n#                    ReportSuggestion \"${TEST_NO}\" \"The JBD (Journal Block Device) driver is not loaded.\" \"Since boot-time, you have not been using any filesystems with journaling. Alternatively, reason could be driver is blacklisted.\"\n#                fi\n#            else\n#                Display --indent 2 --text \"- JBD driver: unable to check\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n#                LogText \"Kernel is monolithic - cannot check if JBD driver is part of compiled kernel.\"\n#            fi\n#        else\n#            Display --indent 2 --text \"- JBD driver: test skipped\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n#            LogText \"Test skipped as the kernel type (monolithic/modular) is unknown\"\n#        fi\n#    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6410\n    # Description : Checking locate database (file index)\n    # Notes       : Linux     /var/lib/mlocate/mlocate.db or /var/lib/slocate/slocate.db\n    #                       or /var/cache/locate/locatedb\n    #               FreeBSD /var/db/locate.database\n    if [ ! \"${LOCATEBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FILE-6410 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --category security --description \"Checking Locate database\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking locate database\"\n        FOUND=0\n        LOCATE_DBS=\"${ROOTDIR}var/cache/locate/locatedb ${ROOTDIR}var/db/locate.database ${ROOTDIR}var/lib/locate/locatedb ${ROOTDIR}var/lib/locatedb ${ROOTDIR}var/lib/mlocate/mlocate.db ${ROOTDIR}var/lib/plocate/plocate.db ${ROOTDIR}var/lib/slocate/slocate.db\"\n        for FILE in ${LOCATE_DBS}; do\n            if [ -f ${FILE} ]; then\n                LogText \"Result: locate database found (${FILE})\"\n                FOUND=1\n                LOCATE_DB=\"${FILE}\"\n            else\n                LogText \"Result: file ${FILE} not found\"\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking Locate database\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"locate_db=${LOCATE_DB}\"\n        else\n            LogText \"Result: database not found\"\n            Display --indent 2 --text \"- Checking Locate database\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"The database required for 'locate' could not be found. Run 'updatedb' or 'locate.updatedb' to create this file.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FILE-6420 TODO\n    # Description : Check automount process\n\n    # Want to contribute to Lynis? Create this test\n\n#\n#################################################################################\n#\n    # Test        : FILE-6422 TODO\n    # Description : Check automount maps (files or for example LDAP based)\n    # Notes       : Warn when automounter is running\n\n    # Want to contribute to Lynis? Create this test\n\n#\n#################################################################################\n#\n    # Test        : FILE-6424 TODO\n    # Description : Check automount map files\n\n    # Want to contribute to Lynis? Create this test\n\n#\n#################################################################################\n#\n    # Test        : FILE-6425 TODO\n    # Description : Check mounted files systems via automounter\n    # Notes       : Warn when no systems are mounted?\n\n    # Want to contribute to Lynis? Create this test\n\n#\n#################################################################################\n#\n    # Test        : FILE-6430\n    # Description : Disable mounting of some filesystems\n    # Rationale   : Unless there is a specific reason to use a particular file system, disable it.\n    # Data        : cramfs freevxfs hfs hfsplus jffs2 squashfs udf\n    Register --test-no FILE-6430 --weight L --network NO --category security --description \"Disable mounting of some filesystems\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${LSMODBINARY}\" -a -f /proc/modules ]; then\n            Display --indent 2 --text \"- Disable kernel support of some filesystems\"\n            LIST_FS_NOT_SUPPORTED=\"cramfs freevxfs hfs hfsplus jffs2 squashfs udf\"\n            FOUND=0\n            AVAILABLE_FS=\"\"\n            AVAILABLE_MODPROBE_FS=\"\"\n            for FS in ${LIST_FS_NOT_SUPPORTED}; do\n                # Check if filesystem is present in modprobe output\n                FIND=$(${MODPROBEBINARY} -v -n ${FS} 2>/dev/null | ${GREPBINARY} -E \"/${FS}.ko\" | ${TAILBINARY} -1)\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: found ${FS} support in the kernel (output = ${FIND})\"\n                    Debug \"Module ${FS} present in the kernel\"\n                    LogText \"Test: Checking if ${FS} is active\"\n                    # Check if FS is present in lsmod output\n                    FIND=$(${LSMODBINARY} | ${GREPBINARY} -E \"^${FS}\")\n                    if IsEmpty \"${FIND}\"; then\n                        LogText \"Result: module ${FS} is currently not loaded in the kernel.\"\n                        AddHP 2 3\n                        if IsDebug; then Display --indent 6 --text \"- Module ${FS} not loaded (lsmod)\" --result OK --color GREEN; fi\n                    else\n                        LogText \"Result: module ${FS} is loaded in the kernel\"\n                        Display --indent 4 --text \"- Module $FS loaded in the kernel (lsmod)\" --result \"FOUND\" --color WHITE\n                        FOUND=1\n                        AVAILABLE_MODPROBE_FS=\"${AVAILABLE_MODPROBE_FS}${FS} \"\n                    fi\n                else\n                    AddHP 3 3\n                    if IsDebug; then Display --indent 6 --text \"- Module ${FS} not present in the kernel\" --result OK --color GREEN; fi\n                fi\n                \n                for SUBDIR in \"${ROOTDIR}etc\" \"${ROOTDIR}usr/lib\"; do\n                    if [ -d \"${SUBDIR}/modprobe.d\" ]; then\n                        LogText \"Result: directory ${SUBDIR}/modprobe.d exists\"\n                        FIND=$(${LSBINARY} \"${SUBDIR}/modprobe.d/*\" 2> /dev/null)\n                        if [ -n \"${FIND}\" ]; then\n                            FIND1=$(${GREPBINARY} -E \"^blacklist[[:space:]]+${FS}$\" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v \"#\")\n                            FIND2=$(${GREPBINARY} -E \"^install[[:space:]]+${FS}[[:space:]]+/bin/(true|false)$\" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v \"#\")\n                            if [ -n \"${FIND1}\" ] || [ -n \"${FIND2}\" ]; then\n                                Display --indent 4 --text \"- Module $FS is blacklisted\" --result \"OK\" --color GREEN\n                                LogText \"Result: module ${FS} is blacklisted\"\n                                break\n                            fi\n                        fi\n                    fi\n                done\n            done\n            if [ ${FOUND} -eq 1 ]; then\n                Display --indent 4 --text \"- Discovered kernel modules: ${AVAILABLE_MODPROBE_FS}\"\n                ReportSuggestion \"${TEST_NO}\" \"Consider disabling unused kernel modules\" \"/etc/modprobe.d/blacklist.conf\" \"Add 'install MODULENAME /bin/true' (without quotes)\"\n            fi\n        else\n            LogText \"Test skipped lsmod binary not found or /proc/modules can not be opened\"\n        fi\n        unset AVAILABLE_FS AVAILABLE_MODPROBE_FS\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_firewalls",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Firewalls\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_FIREWALLS}\"\n#\n#################################################################################\n#\n    IPTABLES_ACTIVE=0\n    IP6TABLES_ACTIVE=0\n    IPTABLES_INKERNEL_ACTIVE=0\n    IPTABLES_MODULE_ACTIVE=0\n    FIREWALL_ACTIVE=0\n    FIREWALL_EMPTY_RULESET=0\n    NFTABLES_ACTIVE=0\n#\n#################################################################################\n#\n    # Test        : FIRE-4502\n    # Description : Check iptables kernel module\n    Register --test-no FIRE-4502 --os Linux --weight L --network NO --category security --description \"Check iptables kernel module\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${LSMODBINARY} | ${AWKBINARY} '{ print $1 }' | ${GREPBINARY} \"^ip*_tables\")\n        if [ -n \"${FIND}\" ]; then\n            FIREWALL_ACTIVE=1\n            IPTABLES_ACTIVE=1\n            IPTABLES_MODULE_ACTIVE=1\n            Display --indent 2 --text \"- Checking iptables kernel module\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"firewall_software[]=iptables\"\n            LogText \"Result: Found iptables in loaded kernel modules\"\n            for I in ${FIND}; do\n                if [ \"${I}\" = \"ip6_tables\" ]; then IP6TABLES_ACTIVE=1; Report \"firewall_software[]=ip6tables\"; fi\n                LogText \"Found module: ${I}\"\n            done\n        elif [ -f ${ROOTDIR}proc/net/ip_tables_names ]; then\n            FIREWALL_ACTIVE=1\n            Report \"firewall_software[]=iptables\"\n            IPTABLES_ACTIVE=1\n            Display --indent 2 --text \"- Checking iptables support\" --result \"${STATUS_FOUND}\" --color GREEN\n        elif [ -f ${ROOTDIR}proc/net/ip6_tables_names ]; then\n            FIREWALL_ACTIVE=1\n            IP6TABLES_ACTIVE=1\n            Report \"firewall_software[]=ip6tables\"\n            Display --indent 2 --text \"- Checking ip6tables support\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Checking iptables kernel module\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n\n            # If we can't find an active module, try to find the Linux configuration file and check that\n            if [ -f /proc/config.gz ]; then LINUXCONFIGFILE=\"/proc/config.gz\"; tCATCMD=\"zcat\"; fi\n            sLINUXCONFIGFILE=\"/boot/config-$(uname -r)\"\n            if [ -f ${sLINUXCONFIGFILE} ]; then LINUXCONFIGFILE=${sLINUXCONFIGFILE}; tCATCMD=\"cat\"; fi\n\n            # If we have a kernel configuration file, use it for testing\n            # Do not perform test if we already found it in kernel module list, to avoid triggered it in the upcoming\n            # tests, when using iptables --list\n            if [ -n \"${LINUXCONFIGFILE}\" ]; then\n                if [ -f ${LINUXCONFIGFILE} -a ${IPTABLES_MODULE_ACTIVE} -eq 0 ]; then\n                    LogText \"Result: found kernel configuration file (${LINUXCONFIGFILE})\"\n                    FIND=$(${tCATCMD} ${LINUXCONFIGFILE} | ${GREPBINARY} -v '^#' | ${GREPBINARY} \"CONFIG_IP_NF_IPTABLES\" | head -n 1)\n                    if [ -n \"${FIND}\" ]; then\n                        HAVEMOD=$(echo ${FIND} | ${CUTBINARY} -d '=' -f2)\n                        # Do not use iptables if it's compiled as a module (=m), since we already tested for it in the\n                        # active list.\n                        if [ \"${HAVEMOD}\" = \"y\" ]; then\n                            LogText \"Result: iptables available as a module in the configuration\"\n                            IPTABLES_ACTIVE=1\n                            IPTABLES_INKERNEL_ACTIVE=1\n                            FIREWALL_ACTIVE=1\n                            Display --indent 2 --text \"- Checking iptables in config file\" --result \"${STATUS_FOUND}\" --color GREEN\n                        else\n                            LogText \"Result: no iptables found in Linux kernel config file\"\n                        fi\n                    else\n                        LogText \"Result: no Linux configuration file found\"\n                        Display --indent 2 --text \"- Checking iptables in config file\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n                    fi\n                fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4508\n    # Description : Check iptables chain policies\n    # Notes       : Suggestions are currently disabled, until related page and documentation is available\n    # TODO        : grep -z is not supported on BusyBox\n    if [ ! \"${IPTABLESBINARY}\" = \"\" -a ${IPTABLES_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4508 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description \"Check used policies of iptables chains\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 4 --text \"- Checking iptables policies of chains\" --result \"${STATUS_FOUND}\" --color GREEN\n        IPTABLES_TABLES=\"filter nat mangle raw security\"\n        for IPTABLES_TABLE in ${IPTABLES_TABLES}\n        do\n            ${IPTABLESBINARY} -t \"${IPTABLES_TABLE}\" --list-rules --wait 1 2>/dev/zero |\n            {\n                IPTABLES_OUTPUT_QUEUE=\"\"\n                while IFS=\"$(printf '\\n')\" read -r IPTABLES_LINES\n                do\n                    set -- ${IPTABLES_LINES}\n                    while [ $# -gt 0 ]; do\n                        if [ \"${1}\" = \"-P\" ]; then\n                            IPTABLES_CHAIN=\"${2}\"\n                            IPTABLES_TARGET=\"${3}\"\n                            shift 3\n                        elif [ \"${1}\" = \"-A\" ] || [ \"${1}\" = \"-N\" ]; then\n                            IPTABLES_CHAIN=\"${2}\"\n                            shift 2\n                        elif [ \"${1}\" = \"-j\" ]; then\n                            IPTABLES_TARGET=\"${2}\"\n                            shift\n                        else\n                            shift\n                        fi\n                    done\n                    # logics\n                    if [ \"${IPTABLES_TABLE}\" = \"filter\" ] || [ \"${IPTABLES_TABLE}\" = \"security\" ]; then\n                        if [ \"${IPTABLES_CHAIN}\" = \"INPUT\" ]; then\n                            if [ \"${IPTABLES_TARGET}\" = \"ACCEPT\" ]; then\n                                IPTABLES_OUTPUT_QUEUE=\"${IPTABLES_OUTPUT_QUEUE}\\n${IPTABLES_TABLE} ${IPTABLES_CHAIN} ${IPTABLES_TARGET} YELLOW 1 3\"\n                            elif [ \"${IPTABLES_TARGET}\" = \"DROP\" ]; then\n                                IPTABLES_OUTPUT_QUEUE=\"${IPTABLES_OUTPUT_QUEUE}\\n${IPTABLES_TABLE} ${IPTABLES_CHAIN} ${IPTABLES_TARGET} GREEN 3 3\"\n                            fi\n                        fi\n                        if [ \"${IPTABLES_CHAIN}\" = \"INPUT\" ] || [ \"${IPTABLES_CHAIN}\" = \"FORWARD\" ] || [ \"${IPTABLES_CHAIN}\" = \"OUTPUT\" ]; then\n                            if [ \"${IPTABLES_TARGET}\" = \"NFQUEUE\" ]; then\n                                IPTABLES_OUTPUT_QUEUE=\"${IPTABLES_OUTPUT_QUEUE}\\n${IPTABLES_TABLE} ${IPTABLES_CHAIN} ${IPTABLES_TARGET} RED 0 3\"\n                            fi\n                        fi\n                    fi\n                done\n                if [ -n \"${IPTABLES_OUTPUT_QUEUE}\" ]; then\n                    # Sort output if sort tool is available\n                    if [ -n \"${SORTBINARY}\" ]; then\n                        LogText \"Info: sorting output\"\n                        IPTABLES_OUTPUT=\"$(printf '%b' \"${IPTABLES_OUTPUT_QUEUE}\" | ${SORTBINARY} -u )\"\n                    else\n                        IPTABLES_OUTPUT=\"$(printf '%b' \"${IPTABLES_OUTPUT_QUEUE}\")\"\n                    fi\n                    printf '%b\\n' \"${IPTABLES_OUTPUT}\" | while IFS=\"$(printf '\\n')\" read -r IPTABLES_OUTPUT_LINE\n                    do\n                        if [ -n \"$IPTABLES_OUTPUT_LINE\" ]; then\n                            set -- ${IPTABLES_OUTPUT_LINE}\n                            while [ $# -gt 0 ]; do\n                                LogText \"Result: Found target '${3}' for chain '${2}' (table: ${1})\"\n                                Display --indent 6 --text \"- Chain ${2} (table: ${1}, target: ${3})\" --result \"${3}\" --color \"${4}\"\n                                if [ \"${3}\" = \"NFQUEUE\" ]\n                                then\n                                    ReportSuggestion \"${TEST_NO}\" \"Consider avoid ${3} target if possible (iptables chain ${2}, table: ${1})\"\n                                fi\n                                AddHP \"${5}\" \"${6}\"\n                                shift 6\n                            done\n                        fi\n                    done\n                fi\n            }\n            unset IPTABLES_TABLE\n        done\n        unset IPTABLES_TABLES\n    fi\n    unset PREQS_MET\n#\n#################################################################################\n#\n    # Test        : FIRE-4512\n    # Description : Check iptables for empty ruleset (should have at least 5 or more rules)\n    if [ -n \"${IPTABLESBINARY}\" -a ${IPTABLES_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4512 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description \"Check iptables for empty ruleset\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${IPTABLESBINARY} --list --numeric 2> /dev/null | ${GREPBINARY} -E -v \"^(Chain|target|$)\" | ${WCBINARY} -l | ${TRBINARY} -d ' ')\n        if [ -n \"${FIND}\" ]; then\n            FIREWALL_ACTIVE=1\n            if [ ${FIND} -le 5 ]; then\n                # Firewall is active, but needs configuration\n                FIREWALL_EMPTY_RULESET=1\n                LogText \"Result: iptables ruleset seems to be empty (found ${FIND} rules)\"\n                Display --indent 4 --text \"- Checking for empty ruleset\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"iptables module(s) loaded, but no rules active\"\n            else\n                LogText \"Result: one or more rules are available (${FIND} rules)\"\n                Display --indent 4 --text \"- Checking for empty ruleset\" --result \"${STATUS_OK}\" --color GREEN\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4513\n    # Description : Check iptables for unused rules\n    if [ -n \"${IPTABLESBINARY}\" -a ${IPTABLES_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4513 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --root-only YES --category security --description \"Check iptables for unused rules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${IPTABLESBINARY} --list --numeric --line-numbers --verbose | ${AWKBINARY} '{ if ($2==\"0\") print $1 }' | ${XARGSBINARY})\n        if IsEmpty \"${FIND}\"; then\n            Display --indent 4 --text \"- Checking for unused rules\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: There are no unused rules present\"\n        else\n            Display --indent 4 --text \"- Checking for unused rules\" --result \"${STATUS_FOUND}\" --color YELLOW\n            LogText \"Result: Found one or more possible unused rules\"\n            LogText \"Description: Unused rules can be a sign that the firewall rules aren't optimized or up-to-date\"\n            LogText \"Note: Sometimes rules aren't triggered but still in use. Keep this in mind before cleaning up rules.\"\n            LogText \"Output: iptables rule numbers: ${FIND}\"\n            ReportSuggestion \"${TEST_NO}\" \"Check iptables rules to see which rules are currently not used\"\n            LogText \"Tip: iptables --list --numeric --line-numbers --verbose\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4514\n    # Notes       :\n    # Check if ipv6 is active on any network interface\n    # If ip_tables is active, and ip6_tables is not, show warning about missing filtering\n#\n#################################################################################\n#\n\n    # Test        : FIRE-4518\n    # Description : Checking status of pf firewall components\n    # Notes       : Use /dev/pf as first detection method if pf is available\n    if [ -e /dev/pf ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No /dev/pf device\"; fi\n    Register --test-no FIRE-4518 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --root-only YES --category security --description \"Check pf firewall components\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        PFFOUND=0; PFLOGDFOUND=0\n\n        # Check status with pfctl\n        LogText \"Test: checking pf status via pfctl\"\n        if [ -n \"${PFCTLBINARY}\" ]; then\n            FIND=$(${PFCTLBINARY} -sa 2>&1 | ${GREPBINARY} \"^Status\" | ${HEADBINARY} -1 | ${AWKBINARY} '{ print $2 }')\n            if [ \"${FIND}\" = \"Disabled\" ]; then\n                if IsVerbose; then Display --indent 2 --text \"- Checking pf status (pfctl)\" --result \"${STATUS_DISABLED}\" --color RED; fi\n                LogText \"Result: pf is disabled\"\n                AddHP 0 3\n            elif [ \"${FIND}\" = \"Enabled\" ]; then\n                Display --indent 2 --text \"- Checking pf status (pfctl)\" --result \"${STATUS_ENABLED}\" --color GREEN\n                LogText \"Result: pf is enabled\"\n                PFFOUND=1\n                AddHP 3 3\n            else\n                Display --indent 2 --text \"- Checking pf status (pfctl)\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n                ReportException ${TEST_NO} \"Unknown status of pf firewall\"\n            fi\n        fi\n\n        # If we didn't find the status to be enabled, stop searching\n        if [ ${PFFOUND} -eq 0 ]; then\n            # Check for pf kernel module (FreeBSD and similar)\n            LogText \"Test: searching for pf kernel module\"\n            if [ -n \"${KLDSTATBINARY}\" ]; then\n                FIND=$(${KLDSTATBINARY} | ${GREPBINARY} 'pf.ko')\n                if [ -z \"${FIND}\" ]; then\n                    LogText \"Result: Can not find pf KLD\"\n                else\n                    LogText \"Result: pf KLD loaded\"\n                    PFFOUND=1\n                fi\n            else\n                LogText \"Result: no kldstat binary, skipping this part\"\n            fi\n\n            if IsRunning \"pflogd\"; then\n                LogText \"Result: found pflog daemon in process list\"\n                Display --indent 4 --text \"- Checking pflogd status\" --result \"ACTIVE\" --color GREEN\n                PFFOUND=1\n                PFLOGDFOUND=1\n            else\n                LogText \"Result: pflog daemon not found in process list\"\n            fi\n        fi\n\n        if [ ${PFFOUND} -eq 1 ]; then\n            FIREWALL_ACTIVE=1\n            Report \"firewall_software[]=pf\"\n        else\n            LogText \"Result: pf not running on this system\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4520\n    # Description : Check pf configuration consistency\n    if [ ${PFFOUND} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4520 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check pf configuration consistency\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check /etc/pf.conf\"\n        # Test for warnings (-n don't load the rules)\n        if [ -f /etc/pf.conf ]; then\n            LogText \"Result: /etc/pf.conf exists\"\n            # Check results from pfctl\n            PFWARNINGS=$(${PFCTLBINARY} -n -f /etc/pf.conf -vvv 2>&1 | ${GREPBINARY} -i 'warning')\n            if [ -z \"${PFWARNINGS}\" ]; then\n                Display --indent 4 --text \"- Checking pf configuration consistency\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: no pf filter warnings found\"\n            else\n                Display --indent 4 --text \"- Checking pf configuration consistency\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: found one or more warnings in the pf filter rules\"\n                ReportWarning \"${TEST_NO}\" \"Found one or more warnings in pf configuration file\" \"/etc/pf.conf\" \"text:Run 'pfctl -n -f /etc/pf.conf -vvv' to see available pf warnings\"\n            fi\n        else\n            LogText \"Result: /etc/pf.conf does NOT exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4522\n    # Description : Check ipchains\n#\n#################################################################################\n#\n    # Test        : FIRE-4524\n    # Description : Check for CSF (ConfigServer Security & Firewall)\n    Register --test-no FIRE-4524 --weight L --network NO --category security --description \"Check for CSF presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FILE=\"/etc/csf/csf.conf\"\n        LogText \"Test: check ${FILE}\"\n        if [ -f ${FILE} ]; then\n            LogText \"Result: ${FILE} exists\"\n            FIREWALL_ACTIVE=1\n            Report \"firewall_software[]=csf\"\n            Display --indent 2 --text \"- Checking CSF status (configuration file)\" --result \"${STATUS_FOUND}\" --color GREEN\n\n            LogText \"Test: check if CSF testing mode is disabled\"\n            FIND=$(${GREPBINARY} -P \"^TESTING(\\s|=)\" ${FILE} | ${CUTBINARY} -d= -f2 | ${XARGSBINARY})\n            if [ \"${FIND}\" = \"0\" ]; then\n                Display --indent 4 --text \"- Check if CSF testing mode is disabled\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                Display --indent 4 --text \"- Check if CSF testing mode is disabled\" --result \"${STATUS_WARNING}\" --color RED\n            fi\n\n            LogText \"Test: check if CSF is running\"\n            if [ ! -f /etc/csf/csf.disable ]; then\n                Display --indent 4 --text \"- Check if CSF is running\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                Display --indent 4 --text \"- Check if CSF is running\" --result \"${STATUS_WARNING}\" --color RED\n            fi\n        else\n            LogText \"Result: ${FILE} does NOT exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4526\n    # Description : Check ipf (Solaris)\n    if [ ! \"${IPFBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4526 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check ipf status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${IPFBINARY} -n -V | ${GREPBINARY} \"^Running\" | ${AWKBINARY} '{ print $2 }')\n        if [ \"${FIND}\" = \"yes\" ]; then\n            Display --indent 4 --text \"- Checking ipf status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            LogText \"Result: ipf is enabled and running\"\n            FIREWALL_ACTIVE=1\n            Report \"firewall_software[]=ipf\"\n        else\n            Display --indent 4 --text \"- Checking ipf status\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW\n            LogText \"Result: ipf is not running\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4530\n    # Description : Check IPFW (FreeBSD)\n    Register --test-no FIRE-4530 --os FreeBSD --weight L --network NO --category security --description \"Check IPFW status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${SYSCTLBINARY}\" ]; then\n            # For now, only check for IPv4.\n            FIND=$(${SYSCTLBINARY} net.inet.ip.fw.enable 2> /dev/null | ${AWKBINARY} '{ print $2 }')\n            if [ \"${FIND}\" = \"1\" ]; then\n                Display --indent 2 --text \"- Checking IPFW status\" --result \"${STATUS_RUNNING}\" --color GREEN\n                LogText \"Result: IPFW is running for IPv4\"\n                FIREWALL_ACTIVE=1\n                Report \"firewall_software[]=ipfw\"\n                IPFW_ENABLED=$(service -e | ${GREPBINARY} -o ipfw)\n                if [ \"${IPFW_ENABLED}\" = \"ipfw\" ]; then\n                    Display --indent 4 --text \"- IPFW enabled in /etc/rc.conf\" --result \"${STATUS_YES}\" --color GREEN\n                    LogText \"Result: IPFW is enabled at start-up for IPv4\"\n                else\n                    Display --indent 4 --text \"- ipfw enabled in /etc/rc.conf\" --result \"${STATUS_NO}\" --color YELLOW\n                    LogText \"Result: IPFW is disabled at start-up for IPv4\"\n                fi\n            else\n                if IsVerbose; then Display --indent 2 --text \"- Checking IPFW status\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW; fi\n                LogText \"Result: IPFW is not running for IPv4\"\n            fi\n        else\n            ReportException \"${TEST_NO}:1\" \"No IPFW test available (sysctl missing)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4532\n    # Description : Check Application Firewall in macOS\n    if [ -x /usr/libexec/ApplicationFirewall/socketfilterfw ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4532 --weight L --os \"macOS\" --preqs-met ${PREQS_MET} --network NO --category security --description \"Check macOS application firewall\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2> /dev/null | ${GREPBINARY} \"Firewall is enabled\")\n        if [ -n \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking macOS: Application Firewall\" --result \"${STATUS_ENABLED}\" --color GREEN\n            AddHP 3 3\n            LogText \"Result: application firewall of macOS is enabled\"\n            FIREWALL_ACTIVE=1\n            APPLICATION_FIREWALL_ACTIVE=1\n            Report \"firewall_software[]=macosx-app-fw\"\n            Report \"app_fw[]=macosx-app-fw\"\n        else\n            if IsVerbose; then Display --indent 2 --text \"- Checking macOS: Application Firewall\" --result \"${STATUS_DISABLED}\" --color YELLOW; fi\n            AddHP 1 3\n            LogText \"Result: application firewall of macOS is disabled\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4534\n    # Description : Check outbound firewalls on macOS\n    Register --test-no FIRE-4534 --weight L --os \"macOS\" --network NO --category security --description \"Check for presence of outbound firewalls on macOS\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        FOUND=0\n\n        # Little Snitch Daemon (macOS)\n        LogText \"Test: checking process Little Snitch Daemon\"\n        if IsRunning --full \"Little Snitch Daemon\"; then\n            Display --indent 2 --text \"- Checking Little Snitch Daemon\" --result \"${STATUS_ENABLED}\" --color GREEN\n            LogText \"Result: Little Snitch found\"\n            FOUND=1\n            FIREWALL_ACTIVE=1\n            APPLICATION_FIREWALL_ACTIVE=1\n            Report \"app_fw[]=little-snitch\"\n            Report \"firewall_software[]=little-snitch\"\n        fi\n\n        # HandsOff! Daemon (macOS)\n        LogText \"Test: checking process HandsOffDaemon\"\n        if IsRunning \"HandsOffDaemon\"; then\n            Display --indent 2 --text \"- Checking Hands Off! Daemon\" --result \"${STATUS_ENABLED}\" --color GREEN\n            LogText \"Result: Hands Off! found\"\n            FOUND=1\n            FIREWALL_ACTIVE=1\n            APPLICATION_FIREWALL_ACTIVE=1\n            Report \"app_fw[]=hands-off\"\n            Report \"firewall_software[]=hands-off\"\n        fi\n\n        # LuLu Daemon (macOS)\n        LogText \"Test: checking process LuLu\"\n        if IsRunning \"LuLu\"; then\n            Display --indent 2 --text \"- Checking LuLu Daemon\" --result \"${STATUS_ENABLED}\" --color GREEN\n            LogText \"Result: LuLu found\"\n            FOUND=1\n            FIREWALL_ACTIVE=1\n            APPLICATION_FIREWALL_ACTIVE=1\n            Report \"app_fw[]=lulu\"\n            Report \"firewall_software[]=lulu\"\n        fi\n\n        # Radio Silence (macOS)\n        LogText \"Test: checking process Radio Silence\"\n        if IsRunning --full \"Radio Silence\"; then\n            Display --indent 2 --text \"- Checking Radio Silence\" --result \"${STATUS_ENABLED}\" --color GREEN\n            LogText \"Result: Radio Silence found\"\n            FOUND=1\n            FIREWALL_ACTIVE=1\n            APPLICATION_FIREWALL_ACTIVE=1\n            Report \"app_fw[]=radio-silence\"\n            Report \"firewall_software[]=radio-silence\"\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: outbound firewall not found\"\n            AddHP 1 3\n        else\n            LogText \"Result: found one or more macOS outbound firewall\"\n            AddHP 3 3\n        fi\n\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4536\n    # Description : Check nftables kernel module\n    if HasData \"${NFTBINARY}\"; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4536 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nftables status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${LSMODBINARY} | ${AWKBINARY} '{ print $1 }' | ${GREPBINARY} \"^nf*_tables\")\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found nftables kernel module\"\n            FIREWALL_ACTIVE=1\n            NFTABLES_ACTIVE=1\n            Report \"firewall_software[]=nftables\"\n        else\n            LogText \"Result: no nftables kernel module found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4538\n    # Description : Check nftables configuration\n    if HasData \"${NFTBINARY}\"; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4538 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nftables basic configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Retrieve nft version\n        NFT_VERSION=$(${NFTBINARY} --version 2> /dev/null | ${AWKBINARY} '{ if ($1==\"nftables\") { print $2 }}' | ${TRBINARY} -d 'v')\n        Report \"nft_version=${NFT_VERSION}\"\n        LogText \"Result: found version ${NFT_VERSION} of nft\"\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4540\n    # Description : Check nftables configuration\n    if HasData \"${NFTBINARY}\"; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4540 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description \"Check for empty nftables configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check for empty ruleset\n        NFT_RULES_LENGTH=$(${NFTBINARY} --stateless list ruleset 2> /dev/null | ${GREPBINARY} -E -v \"table|chain|;$|}$|^$\" | ${WCBINARY} -l)\n        if [ ${NFT_RULES_LENGTH} -le 3 ]; then\n            FIREWALL_EMPTY_RULESET=1\n            LogText \"Result: this firewall set has 3 rules or less and is considered to be empty\"\n        else\n            LogText \"Result: found ${NFT_RULES_LENGTH} rules in nftables configuration\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4586\n    # Description : Check firewall logging\n    if [ ${FIREWALL_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no FIRE-4586 --preqs-met ${PREQS_MET} --weight L --network NO --root-only YES --category security --description \"Check firewall logging\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${IPTABLES_ACTIVE} -eq 1 ]; then\n            if [ -n \"${IPTABLESSAVEBINARY}\" ]; then\n                HAS_LOGGING=$(${IPTABLESSAVEBINARY} | ${EGREPBINARY} \"\\-j (NF)?LOG\")\n                if [ -z \"${HAS_LOGGING}\" ]; then\n                    Report \"firewall_no_logging[]=iptables\"\n                fi\n             fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4590\n    # Description : Check if at least one firewall if active\n    Register --test-no FIRE-4590 --weight L --network NO --category security --description \"Check firewall status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${FIREWALL_ACTIVE} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking host based firewall\" --result \"${STATUS_ACTIVE}\" --color GREEN\n            LogText \"Result: host based firewall or packet filter is active\"\n            Report \"manual[]=Verify if there is a formal process for testing and applying firewall rules\"\n            Report \"manual[]=Verify all traffic is filtered the right way between the different security zones\"\n            Report \"manual[]=Verify if a list is available with all required services\"\n            # YYY Solaris ipf (determine default policy)\n            Report \"manual[]=Make sure an explicit deny all is the default policy for all unmatched traffic\"\n            AddHP 5 5\n        else\n            Display --indent 2 --text \"- Checking host based firewall\" --result \"${STATUS_NOT_ACTIVE}\" --color YELLOW\n            LogText \"Result: no host based firewall/packet filter found or configured\"\n            ReportSuggestion \"${TEST_NO}\" \"Configure a firewall/packet filter to filter incoming and outgoing traffic\"\n            AddHP 0 5\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : FIRE-4594\n    # Description : Check for APF (Advanced Policy Firewall)\n    Register --test-no FIRE-4594 --weight L --network NO --category security --description \"Check for APF presence\"\n    if [ -n \"${IPTABLESBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FILE=\"/etc/apf/conf.apf\"\n        LogText \"Test: check ${FILE}\"\n        if [ -f ${FILE} ]; then\n            LogText \"Result: ${FILE} exists\"\n            FIREWALL_ACTIVE=1\n            Report \"firewall_software[]=apf\"\n            Display --indent 2 --text \"- Checking APF status (configuration file)\" --result \"${STATUS_FOUND}\" --color GREEN\n\n            LogText \"Test: check if APF testing mode is disabled\"\n            FIND=$(${GREPBINARY} -P \"^DEVEL_MODE(\\s|=)\" ${FILE} | ${CUTBINARY} -d= -f2 | ${XARGSBINARY})\n            if [ \"${FIND}\" = \"0\" ]; then\n                Display --indent 4 --text \"- Check if APF testing mode is disabled\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                Display --indent 4 --text \"- Check if APF testing mode is disabled\" --result \"${STATUS_WARNING}\" --color RED\n            fi\n\n            LogText \"Test: check if APF is running\"\n            FIND=$(${IPTABLESBINARY} -L -n | ${GREPBINARY} -iom1 sanity | ${WCBINARY} -l)\n            if [ \"${FIND}\" = \"1\" ]; then\n                Display --indent 4 --text \"- Check if APF is running\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                Display --indent 4 --text \"- Check if APF is running\" --result \"${STATUS_WARNING}\" --color RED\n            fi\n        else\n            LogText \"Result: ${FILE} does NOT exist\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#################################################################################\n#\n    # TODO\n    # Suggestion to disable iptables if nftables is enabled\n    # Check for specific features in nftables releases\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_hardening",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_HARDENING}\"\n\n    # COMPILER_INSTALLED is initialized before\n    HARDEN_COMPILERS_NEEDED=0\n#\n#################################################################################\n#\n    # Test        : HRDN-7220\n    # Description : Check for installed compilers\n    # Notes       : No suggestion for hardening compilers, as HRDN-7222 will take care of that\n    Register --test-no HRDN-7220 --weight L --network NO --category security --description \"Check if one or more compilers are installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check if one or more compilers can be found on the system\"\n        if [ ${COMPILER_INSTALLED} -eq 0 ]; then\n            LogText \"Result: no compilers found\"\n            Display --indent 4 --text \"- Installed compiler(s)\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            LogText \"Result: found installed compiler. See top of logfile which compilers have been found or use ${GREPBINARY} to filter on 'compiler'\"\n            Display --indent 4 --text \"- Installed compiler(s)\" --result \"${STATUS_FOUND}\" --color RED\n            AddHP 1 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HRDN-7222\n    # Description : Check for permissions of installed compilers\n    Register --test-no HRDN-7222 --weight L --network NO --category security --description \"Check compiler permissions\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check if one or more compilers can be found on the system\"\n        HARDEN_COMPILERS_NEEDED=0\n        if [ ${COMPILER_INSTALLED} -eq 0 ]; then\n            LogText \"Result: no compilers found\"\n        else\n            # TODO - c89 c99 cpp ld\n            TEST_BINARIES=\"${ASBINARY} ${CCBINARY} ${CLANGBINARY} ${GCCBINARY}\"\n            for ITEM in ${TEST_BINARIES}; do\n                FILE=\"${ITEM}\"\n                LogText \"Test: Check file permissions for ${ITEM}\"\n                ShowSymlinkPath ${ITEM}\n                if [ -n \"${SYMLINK}\" ]; then\n                    FILE=\"${SYMLINK}\"\n                fi\n\n                if IsWorldExecutable ${FILE}; then\n                    LogText \"Binary: found ${FILE} (world executable)\"\n                    Report \"compiler_world_executable[]=${FILE}\"\n                    AddHP 2 3\n                    HARDEN_COMPILERS_NEEDED=1\n                else\n                    AddHP 3 3\n                fi\n            done\n\n            # Report suggestion is one or more compilers can be better hardened\n            if [ ${HARDEN_COMPILERS_NEEDED} -eq 1 ]; then\n                LogText \"Result: at least one compiler could be better hardened by restricting executable access to root or group only\"\n                ReportSuggestion \"${TEST_NO}\" \"Harden compilers like restricting access to root user only\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HRDN-7230\n    # Description : Check for installed malware scanners\n    Register --test-no HRDN-7230 --weight L --network NO --category security --description \"Check for malware scanner\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check if a malware scanner is installed\"\n        if [ ${MALWARE_SCANNER_INSTALLED} -eq 1 ]; then\n            LogText \"Result: found at least one malware scanner\"\n            Display --indent 4 --text \"- Installed malware scanner\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            LogText \"Result: no malware scanner found\"\n            if [ \"${MACHINE_ROLE}\" = \"personal\" ]; then\n                Display --indent 4 --text \"- Installed malware scanner\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            else\n                Display --indent 4 --text \"- Installed malware scanner\" --result \"${STATUS_NOT_FOUND}\" --color RED\n            fi\n            ReportSuggestion \"${TEST_NO}\" \"Harden the system by installing at least one malware scanner, to perform periodic file system scans\" \"-\" \"Install a tool like rkhunter, chkrootkit, OSSEC, Wazuh\"\n            AddHP 1 3\n            LogText \"Result: no malware scanner found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HRDN-7231\n    # Description : Check for registered non-native binary formats\n    Register --test-no HRDN-7231  --os Linux --weight L --network NO --category security --description \"Check for registered non-native binary formats\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check for registered non-native binary formats\"\n        NFORMATS=0\n        if [ -d /proc/sys/fs/binfmt_misc ]; then\n            NFORMATS=$(${FINDBINARY} /proc/sys/fs/binfmt_misc -type f -not -name register -not -name status | ${WCBINARY} -l)\n        fi\n        if [ ${NFORMATS} -eq 0 ]; then\n            LogText \"Result: no non-native binary formats found\"\n            Display --indent 4 --text \"- Non-native binary formats\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        else\n            FORMATS=$(${FINDBINARY} /proc/sys/fs/binfmt_misc -type f -not -name register -not -name status -printf '%f ')\n            LogText \"Result: found ${NFORMATS} non-native binary formats registered: ${FORMATS}\"\n            Display --indent 4 --text \"- Non-native binary formats\" --result \"${STATUS_FOUND}\" --color RED\n        fi\n    fi\n#\n#################################################################################\n#\n#    LogText \"--------------------------------------------------------------------\"\n#    LogText \"| System part                        | Preferred value | Actual value | Points |\"\n#    LogText \"| [!] Compiler installed               |              0  | [${COMPILER_INSTALLED}]     | x  |\"\n#    LogText \"| [V] Malware scanner installed        |              1  | [x]     | x  |\"\n#    LogText \"| [V] Packet filter enabled            |              1  | [x]     | x  |\"\n#    LogText \"--------------------------------------------------------------------\"\n#    LogText \"| [!]: Hardening possible,  [V]: Hardening performed,  [ ]: Unknown \"\n#    LogText \"--------------------------------------------------------------------\"\n#\n#################################################################################\n#\n\nReport \"compiler_installed=${COMPILER_INSTALLED}\"\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_homedirs",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Home directories\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_HOME_DIRECTORIES}\"\n#\n#################################################################################\n#\n    # Ignore some top level directories (not the sub directories below)\n    IGNORE_HOME_DIRS=\"/bin /boot /cdrom /dev /etc /home /lib /lib64 /media /mnt\n                      /opt /proc /sbin /selinux /srv /sys /tmp /usr /var\"\n#\n#################################################################################\n#\n    # Test        : HOME-9302\n    # Description : Create list with home directories\n    Register --test-no HOME-9302 --weight L --network NO --category security --description \"Create list with home directories\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Read sixth field of /etc/passwd\n        LogText \"Test: query ${ROOTDIR}etc/passwd to obtain home directories\"\n        FIND=$(${AWKBINARY} -F: '{ if ($1 !~ \"#\") print $6 }' ${ROOTDIR}etc/passwd | ${SORTBINARY} -u)\n        for I in ${FIND}; do\n            if [ -d ${I} ]; then\n                LogText \"Result: found home directory: ${I} (directory exists)\"\n                Report \"home_directory[]=${I}\"\n            else\n                LogText \"Result: found home directory: ${I} (directory does not exist)\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : HOME-9304\n    # Description : Check if users' home directories permissions are 750 or more restrictive\n    Register --test-no HOME-9304 --weight L --network NO --category security --description \"Check if users' home directories permissions are 750 or more restrictive\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if users' home directories permissions are 750 or more restrictive\n        FOUND=0\n        USERDATA=$(${GREPBINARY} -E -v '^(daemon|git|halt|root|shutdown|sync)' ${ROOTDIR}etc/passwd | ${AWKBINARY} -F: '($7 !~ \"/(false|nologin)$\") { print }')\n        while read -r LINE; do\n            USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1)\n            DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6)\n            LogText \"Test: checking directory '${DIR}' for user '${USER}'\"\n            if [ -d \"${DIR}\" ]; then\n                WRITE_GROUP_PERM=$(${LSBINARY} -ld ${DIR} | ${CUTBINARY} -f1 -d\" \" | ${CUTBINARY} -c6)\n                OTHER_PERMS=$(${LSBINARY} -ld ${DIR} | ${CUTBINARY} -f1 -d\" \" | ${CUTBINARY} -c8-10)\n                if [ ! ${WRITE_GROUP_PERM} = \"-\" -o ! ${OTHER_PERMS} = \"---\" ]; then\n                    LogText \"Result: permissions of home directory ${DIR} of user ${USER} are not strict enough. Should be 750 or more restrictive. Change with: chmod 750 ${DIR}\"\n                    FOUND=1\n                else\n                    LogText \"Result: permissions of home directory ${DIR} of user ${USER} are fine\"\n                fi\n            fi\n        done << EOF\n${USERDATA}\nEOF\n\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Permissions of home directories\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Double check the permissions of home directories as some might be not strict enough.\"\n        else\n            Display --indent 2 --text \"- Permissions of home directories\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: OK, all permissions of the home directories are 750 or more restrictive\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HOME-9306\n    # Description : Check if users own their home directories\n    Register --test-no HOME-9306 --weight L --network NO --category security --description \"Check if users own their home directories\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if users own their home directories\n        FOUND=0\n        USERDATA=$(${GREPBINARY} -E -v '^(daemon|git|halt|root|shutdown|sync)' ${ROOTDIR}etc/passwd | ${AWKBINARY} -F: '($7 !~ \"/(false|nologin)$\") { print }')\n        while read -r LINE; do\n            USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1)\n            DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6)\n            LogText \"Test: checking directory '${DIR}' for user '${USER}'\"\n            if [ -d \"${DIR}\" ]; then\n                OWNER=$(ls -ld ${DIR} | awk -F\" \" '{ print $3 }')\n                if [ ! \"${OWNER}\" = \"${USER}\" ]; then\n                    LogText \"Result: the home directory ${DIR} of user ${USER} is owned by ${OWNER}. Correct: chown ${USER} ${DIR}\" \n                    FOUND=1\n                else\n                    LogText \"Result: ownership of home directory ${DIR} for user ${USER} looks to be correct\"\n                fi\n            fi\n        done << EOF\n${USERDATA}\nEOF\n\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Ownership of home directories\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Double check the ownership of home directories as some might be incorrect.\"\n        else\n            Display --indent 2 --text \"- Ownership of home directories\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: OK, all users own their home directories\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HOME-9310\n    # Description : Check for suspicious shell history files\n    Register --test-no HOME-9310 --weight L --network NO --category security --description \"Checking for suspicious shell history files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${HOMEDIRS}\" ]; then\n            if [ \"${OS}\" = \"Solaris\" ]; then\n                # Solaris doesn't support -maxdepth\n                FIND=$(${FINDBINARY} ${HOMEDIRS} -name \".*history\" ! -type f -print)\n            else\n                FIND=$(${FINDBINARY} ${HOMEDIRS} -maxdepth 1 -name \".*history\" ! -type f -print)\n            fi\n            if [ -z \"${FIND}\" ]; then\n                Display --indent 2 --text \"- Checking shell history files\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: Ok, history files are type 'file'.\"\n            else\n                Display --indent 2 --text \"- Checking shell history files\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: the following files seem to be of the wrong file type:\"\n                LogText \"Output: ${FIND}\"\n                LogText \"Info: above files could be redirected files to avoid logging and should be investigated\"\n                ReportWarning \"${TEST_NO}\" \"Incorrect file type found for shell history file\"\n            fi\n            LogText \"Remark: History files are normally of the type 'file'. Symbolic links and other types are suspicious.\"\n        else\n            Display --indent 2 --text \"- Checking shell history files\" --result \"${STATUS_SKIPPED}\" --color WHITE\n            LogText \"Result: Homedirs is empty, therefore test will be skipped\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HOME-9314\n    # Description : Check if non local paths are found in PATH, which can be a risk, but also bad for performance\n    #               (like searching on a filer, instead of local disk)\n    #Register --test-no HOME-9314 --weight L --network NO --category security --description \"Create list with home directories\"\n#\n#################################################################################\n#\n    # Test        : HOME-9350\n    # Description : Scan home directories for specific files, used in different tests later\n    # Notes       : For performance reasons we combine the scanning of different files, so inode caching is used\n    #               as much as possible for every find command\n    # Profile opt : ignore-home-dir (multiple lines allowed), ignores home directory\n    if [ -n \"${REPORTFILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HOME-9350 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Collecting information from home directories\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        IGNORE_HOME_DIRS=$(${GREPBINARY} \"^ignore-home-dir=\" ${REPORTFILE} | ${AWKBINARY} -F= '{ print $2 }')\n        if [ -z \"${IGNORE_HOME_DIRS}\" ]; then\n            LogText \"Result: IGNORE_HOME_DIRS empty, no paths excluded\"\n        else\n            LogText \"Output: ${IGNORE_HOME_DIRS}\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_insecure_services",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Insecure services\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_INSECURE_SERVICES}\"\n#\n#################################################################################\n#\n    INETD_ACTIVE=0\n    INETD_CONFIG_FILE=\"${ROOTDIR}etc/inetd.conf\"\n    INETD_PACKAGE_INSTALLED=0\n    XINETD_ACTIVE=0\n    XINETD_CONFIG_FILE=\"${ROOTDIR}etc/xinetd.conf\"\n    XINETD_CONFIG_DIR=\"${ROOTDIR}etc/xinetd.d\"\n#\n#################################################################################\n#\n    # Test        : INSE-8000\n    # Description : Check for installed inetd package\n    Register --test-no INSE-8000 --package-manager-required --weight L --network NO --category security --description \"Installed inetd package\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check for installed inetd daemon\n        LogText \"Test: Checking if inetd is installed\"\n        if PackageIsInstalled \"inetd\" || PackageIsInstalled \"inetutils-inetd\"; then\n            INETD_PACKAGE_INSTALLED=1\n            LogText \"Result: inetd is installed\"\n            Display --indent 2 --text \"- Installed inetd package\" --result \"${STATUS_FOUND}\" --color YELLOW\n            #ReportSuggestion \"${TEST_NO}\" \"If there are no inetd services required, it is recommended that the daemon be removed\"\n        else\n            LogText \"Result: inetd is NOT installed\"\n            Display --indent 2 --text \"- Installed inetd package\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8002\n    # Description : Check for inetd status\n    if [ ${INETD_PACKAGE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8002 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for enabled inet daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check running processes\n        LogText \"Test: Searching for active inet daemon\"\n        if IsRunning \"inetd\" || IsRunning \"inetutils-inetd\"; then\n            LogText \"Result: inetd is running\"\n            Display --indent 4 --text \"- inetd status\" --result \"${STATUS_ACTIVE}\" --color GREEN\n            INETD_ACTIVE=1\n        else\n            LogText \"Result: inetd is NOT running\"\n            Display --indent 4 --text \"- inetd status\" --result \"${STATUS_NOT_ACTIVE}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8004\n    # Description : Check for inetd configuration file (inetd)\n    if [ ${INETD_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8004 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Presence of inetd configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check configuration file\n        LogText \"Test: Searching for file ${INETD_CONFIG_FILE}\"\n        if [ -f ${INETD_CONFIG_FILE} ]; then\n            LogText \"Result: ${INETD_CONFIG_FILE} exists\"\n            Display --indent 4 --text \"- Checking inetd.conf\" --result \"${STATUS_FOUND}\" --color WHITE\n        else\n            LogText \"Result: ${INETD_CONFIG_FILE} does not exist\"\n            Display --indent 4 --text \"- Checking inetd.conf\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8006\n    # Description : Check for inetd configuration file contents if inetd is NOT active\n    if [ ${INETD_ACTIVE} -eq 0 -a -f ${INETD_CONFIG_FILE} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8006 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check configuration of inetd when disabled\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if any service is enabled in /etc/inetd.conf (inetd is not active, see test INSE-8002)\n        LogText \"Test: check if all services are disabled when inetd is disabled\"\n        FIND=$(${GREPBINARY} -v \"^#\" ${INETD_CONFIG_FILE} | ${GREPBINARY} -v \"^$\")\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: no services found in ${INETD_CONFIG_FILE}\"\n            Display --indent 4 --text \"- Checking enabled inetd services\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: found services in inetd, even though inetd is not running\"\n            Display --indent 4 --text \"- Checking enabled inetd services\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Although inetd is not running, make sure no services are enabled in ${INETD_CONFIG_FILE}, or remove inetd service\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8016\n    # Description : Check for telnet enabled via inetd\n    if [ ${INETD_ACTIVE} -eq 1 -a -f ${INETD_CONFIG_FILE} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8016 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for telnet via inetd\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking telnet presence in inetd configuration\"\n        FIND=$(${GREPBINARY} \"^telnet\" ${INETD_CONFIG_FILE})\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: telnet not enabled in ${INETD_CONFIG_FILE}\"\n            Display --indent 2 --text \"- Checking inetd (telnet)\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            LogText \"Result: telnet enabled in ${INETD_CONFIG_FILE}\"\n            Display --indent 2 --text \"- Checking inetd (telnet)\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Disable telnet in inetd configuration and use SSH instead\"\n            AddHP 1 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8100\n    # Description : Check for installed xinetd daemon\n    Register --test-no INSE-8100 --package-manager-required --weight L --network NO --category security --description \"Check for installed xinetd daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check for installed xinetd daemon\n        LogText \"Test: Checking for installed xinetd daemon\"\n        if PackageIsInstalled \"xinetd\"; then\n            LogText \"Result: xinetd is installed\"\n            Display --indent 2 --text \"- Installed xinetd package\" --result \"${STATUS_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"If there are no xinetd services required, it is recommended that the daemon be removed\"\n        else\n            LogText \"Result: xinetd is NOT installed\"\n            Display --indent 2 --text \"- Installed xinetd package\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8102\n    # Description : Check for xinetd status\n    Register --test-no INSE-8102 --weight L --network NO --category security --description \"Check for active xinet daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check running processes\n        LogText \"Test: Searching for active extended internet services daemon (xinetd)\"\n        if IsRunning \"xinetd\"; then\n            LogText \"Result: xinetd is running\"\n            Display --indent 4 --text \"- xinetd status\" --result \"${STATUS_ACTIVE}\" --color GREEN\n            XINETD_ACTIVE=1\n        else\n            LogText \"Result: xinetd is NOT running\"\n            Display --indent 4 --text \"- xinetd status\" --result \"${STATUS_NOT_ACTIVE}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8104\n    # Description : Check for xinetd configuration file\n    if [ ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8104 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for enabled xinet daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check configuration file\n        LogText \"Test: Searching for file ${XINETD_CONFIG_FILE}\"\n        if [ -f \"${XINETD_CONFIG_FILE}\" ]; then\n            LogText \"Result: ${XINETD_CONFIG_FILE} exists\"\n            Display --indent 6 --text \"- Configuration file (xinetd.conf)\" --result \"${STATUS_FOUND}\" --color WHITE\n        else\n            LogText \"Result: ${XINETD_CONFIG_FILE} does not exist\"\n            Display --indent 6 --text \"- Configuration file (xinetd.conf)\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8106\n    # Description : Check for xinetd configuration file contents if xinetd is NOT active\n    if [ ${XINETD_ACTIVE} -eq 0 -a -f ${XINETD_CONFIG_FILE} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8106 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check configuration of xinetd when disabled\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if any service is enabled in /etc/xinetd.d (xinetd is not active, see test INSE-8102)\n        LogText \"Test: check if all services are disabled if xinetd is disabled\"\n        FIND=$(${GREPBINARY} -r \"disable\\s*=\\s*no\" ${XINETD_CONFIG_DIR})\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: no services found in ${XINETD_CONFIG_DIR}\"\n            Display --indent 6 --text \"- Enabled xinetd.d services\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        else\n            LogText \"Result: found services in ${XINETD_CONFIG_DIR}, even though xinetd is not running\"\n            Display --indent 6 --text \"- Enabled xinetd.d services\" --result \"${STATUS_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Although xinetd is not running, make sure no services are enabled in ${XINETD_CONFIG_DIR}, or remove xinetd service\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8116\n    # Description : Check for insecure services enabled via xinetd\n    if [ ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8116 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Insecure services enabled via xinetd\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        XINETD_INSECURE_SERVICE_FOUND=0\n\n        ITEMS=\"chargen chargen-dgram chargen-stream daytime daytime-dgram daytime-stream discard discard-dgram discard-stream echo echo-dgram echo-stream time time-dgram time-stream ntalk rexec rlogin rsh rsync talk telnet tftp\"\n\n        for SERVICE in ${ITEMS}; do\n            LogText \"Test: checking service ${SERVICE}\"\n            if ! SkipAtomicTest \"${TEST_NO}:${SERVICE}\"; then\n                FILE=\"${XINETD_CONFIG_DIR}/${SERVICE}\"\n                if [ -f \"${FILE}\" ]; then\n                    LogText \"Test: checking status in xinetd configuration file (${FILE})\"\n                    FIND=$(${GREPBINARY} \"disable\\s*=\\s*no\" ${FILE})\n                    if [ -n \"${FIND}\" ]; then\n                        LogText \"Result: found insecure service enabled: ${SERVICE}\"\n                        XINETD_INSECURE_SERVICE_FOUND=1\n                        ReportSuggestion \"${TEST_NO}\" \"Disable or remove any insecure services in the xinetd configuration\" \"${SERVICE}\" \"text:See log file for more details\"\n                        Report \"insecure_service[]=${SERVICE}\"\n                    fi\n                fi\n            else\n                LogText \"Result: skipped, as this item is excluded using the profile\"\n            fi\n        done\n\n        if [ ${XINETD_INSECURE_SERVICE_FOUND} -eq 0 ]; then\n            LogText \"Result: no insecure services found in xinetd configuration\"\n            Display --indent 6 --text \"- Checking xinetd (insecure services)\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 3 3\n        else\n            LogText \"Result: one ore more insecure services discovered in xinetd configuration\"\n            Display --indent 6 --text \"- Checking xinetd (insecure services)\" --result \"${STATUS_WARNING}\" --color RED\n            AddHP 0 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8200\n    # Description : Check if tcp_wrappers is installed when inetd/xinetd is active\n    if [ ${INETD_ACTIVE} -eq 1 -o ${XINETD_ACTIVE} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no INSE-8200 --package-manager-required --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check if tcp_wrappers is installed when inetd/xinetd is active\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if tcp_wrappers is installed\"\n        FOUND=0\n        PACKAGES=\"tcp_wrappers tcpd\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then LogText \"Package '${PACKAGE}' is installed\"; FOUND=1; fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: tcp_wrappers is installed\"\n            Display --indent 2 --text \"- Checking tcp_wrappers installation\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: tcp_wrappers is NOT installed\"\n            Display --indent 2 --text \"- Checking tcp_wrappers installation\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            #ReportSuggestion \"${TEST_NO}\" \"When network services are using the inetd/xinetd service, the tcp_wrappers package should be installed\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8300\n    # Description : Check if rsh client is installed\n    Register --test-no INSE-8300 --package-manager-required --weight L --network NO --category security --description \"Check if rsh client is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if rsh client is installed\"\n        FOUND=0\n        PACKAGES=\"rsh rsh-client rsh-redone-client\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then LogText \"Package '${PACKAGE}' is installed\"; FOUND=1; fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: rsh client is installed\"\n            Display --indent 2 --text \"- Installed rsh client package\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Remove rsh client when it is not in use or replace with the more secure SSH package\"\n        else\n            LogText \"Result: rsh client is NOT installed\"\n            Display --indent 2 --text \"- Installed rsh client package\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8302\n    # Description : Check presence of rsh Trust Files\n    #Register --test-no INSE-8302 --weight L --network NO --category security --description \"Check presence of rsh Trust Files\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    #    # Check presence of Rsh Trust Files\n    #    FOUND=0\n    #    for LINE in $(${CAT_BINARY} /etc/passwd | ${GREPBINARY} -E -v '^(root|halt|sync|shutdown)' | ${AWKBINARY} -F: '($7 !=\"/sbin/nologin\" && $7 != \"/bin/false\") { print }'); do\n    #        USER=$(echo ${LINE} | ${CUTBINARY} -d: -f1)\n    #        DIR=$(echo ${LINE} | ${CUTBINARY} -d: -f6)\n    #            if [ -d ${DIR} ]; then\n    #                for RHOSTS in ${DIR}/.rhosts; do\n    #                    if [ ! -h ${RHOSTS} -a -f ${RHOSTS} ]; then\n    #                        LogText \"FOUND .rhosts file in home directory ${DIR} of ${USER}\"\n    #                        FOUND=1\n    #                    fi\n    #                done\n    #            fi\n    #    done\n    #    if [ -f /etc/hosts.equiv ];then\n    #        LogText \"FOUND /etc/hosts.equiv\"\n    #        FOUND=1\n    #    fi\n    #    if [ ${FOUND} -eq 1 ]; then\n    #        LogText \"Result: found one or more Rsh Trust Files\"\n    #        Display --indent 4 --text \"- Checking presence of Rsh Trust Files\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n    #        ReportSuggestion \"${TEST_NO}\" \"Remove every Rsh Trust Files as they can allow unauthenticated access to a system\"\n    #    else\n    #        LogText \"Result: no Rsh Trust Files found\"\n    #        Display --indent 4 --text \"- Checking presence of Rsh Trust Files\" --result \"${STATUS_OK}\" --color GREEN\n    #    fi\n    #fi\n#\n#################################################################################\n#\n    # Test        : INSE-8304\n    # Description : Check if rsh server is installed\n    Register --test-no INSE-8304 --package-manager-required --weight L --network NO --category security --description \"Check if rsh server is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if rsh server is installed\n        LogText \"Test: Checking if rsh server is installed\"\n        FOUND=0\n        PACKAGES=\"rsh-server rsh-redone-server\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then LogText \"Package '${PACKAGE}' is installed\"; FOUND=1; fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: rsh server is installed\"\n            Display --indent 2 --text \"- Installed rsh server package\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Remove the rsh-server package and replace with a more secure alternative like SSH\"\n            Report \"insecure_service[]=rsh-server\"\n        else\n            LogText \"Result: rsh server is NOT installed\"\n            Display --indent 2 --text \"- Installed rsh server package\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8310\n    # Description : Check if telnet client is installed\n    Register --test-no INSE-8310 --package-manager-required --weight L --network NO --category security --description \"Check if telnet client is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if telnet client is installed\n        LogText \"Test: Checking if telnet client is installed\"\n        if PackageIsInstalled \"${PACKAGE}\"; then LogText \"Package '${PACKAGE}' is installed\"; FOUND=1; fi\n\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: telnet client is installed\"\n            Display --indent 2 --text \"- Installed telnet client package\" --result \"${STATUS_FOUND}\" --color YELLOW\n            # Telnet client usage might be used for troubleshooting instead of system administration\n            #ReportSuggestion \"${TEST_NO}\" \"telnet client contain numerous security exposures and have been replaced with the more secure SSH package\"\n        else\n            LogText \"Result: telnet client is NOT installed\"\n            Display --indent 2 --text \"- Installed telnet client package\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8322\n    # Description : Check if telnet server is installed\n    Register --test-no INSE-8322 --package-manager-required --weight L --network NO --category security --description \"Check if telnet server is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if TFTP server is installed\n        LogText \"Test: Checking if telnet server is installed\"\n        FOUND=0\n        PACKAGES=\"telnetd telnet-server\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then LogText \"Package '${PACKAGE}' is installed\"; FOUND=1; fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: telnet server is installed\"\n            Display --indent 2 --text \"- Installed telnet server package\" --result \"${STATUS_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Removing the telnet server package and replace with SSH when possible\"\n            Report \"insecure_service[]=telnet-server\"\n        else\n            LogText \"Result: telnet server is NOT installed\"\n            Display --indent 2 --text \"- Installed telnet server package\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        fi\n    fi\n\n#\n#################################################################################\n#\n    # Test        : INSE-8314\n    # Description : Check if NIS client is installed\n    Register --test-no INSE-8314 --package-manager-required --weight L --network NO --category security --description \"Check if NIS client is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=\"\"\n        LogText \"Test: Checking if NIS client is installed\"\n        PACKAGES=\"nis ypbind\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then\n                FOUND=\"${PACKAGE}\"\n            fi\n        done\n        if [ -n \"${FOUND}\" ]; then\n            LogText \"Result: NIS client is installed\"\n            Display --indent 2 --text \"- Checking NIS client installation\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"NIS client should be removed if not required. Use a more secure alternative or a protocol that can use encrypted communications.\"\n        else\n            LogText \"Result: NIS client is NOT installed\"\n            Display --indent 2 --text \"- Checking NIS client installation\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8316\n    # Description : Check if NIS server is installed\n    Register --test-no INSE-8316 --package-manager-required --weight L --network NO --category security --description \"Check if NIS server is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=\"\"\n        LogText \"Test: Checking if NIS server is installed\"\n        PACKAGES=\"nis ypserv\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then\n                FOUND=\"${PACKAGE}\"\n            fi\n        done\n        if [ -n \"${FOUND}\" ]; then\n            LogText \"Result: NIS server is installed\"\n            Display --indent 2 --text \"- Checking NIS server installation\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Removing the ${FOUND} package decreases the risk of the accidental (or intentional) activation of NIS or NIS+ services\"\n        else\n            LogText \"Result: NIS server is NOT installed\"\n            Display --indent 2 --text \"- Checking NIS server installation\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8318\n    # Description : Check if TFTP client is installed\n    Register --test-no INSE-8318 --package-manager-required --weight L --network NO --category security --description \"Check if TFTP client is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if TFTP client is installed\"\n        FOUND=\"\"\n        PACKAGES=\"atftp tftp tftp-hpa\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then\n                FOUND=\"${PACKAGE}\"\n            fi\n        done\n        if [ -n \"${FOUND}\" ]; then\n            LogText \"Result: TFTP client is installed\"\n            Display --indent 2 --text \"- Checking TFTP client installation\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"It is recommended that TFTP be removed, unless there is a specific need for TFTP (such as a boot server)\"\n        else\n            LogText \"Result: TFTP client is NOT installed\"\n            Display --indent 2 --text \"- Checking TFTP client installation\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8320\n    # Description : Check if TFTP server is installed\n    Register --test-no INSE-8320 --package-manager-required --weight L --network NO --category security --description \"Check if TFTP server is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking if TFTP server is installed\"\n        FOUND=\"\"\n        PACKAGES=\"atftpd tftpd tftp-server tftpd-hpa\"\n        for PACKAGE in ${PACKAGES}; do\n            if PackageIsInstalled \"${PACKAGE}\"; then\n                FOUND=\"${PACKAGE}\"\n            fi\n        done\n        if [ -n \"${FOUND}\" ]; then\n            LogText \"Result: TFTP server is installed\"\n            Display --indent 2 --text \"- Checking TFTP server installation\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Removing the ${FOUND} package decreases the risk of the accidental (or intentional) activation of tftp services\"\n        else\n            LogText \"Result: TFTP server is NOT installed\"\n            Display --indent 2 --text \"- Checking TFTP server installation\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : INSE-8050\n    # Description : Check for insecure services on macOS\n    if [ -n \"${LAUNCHCTL_BINARY}\" ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No launchctl binary on this system\"; fi\n    Register --test-no INSE-8050 --os \"macOS\" --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight M --network NO --category security --description \"Check for insecure services on macOS\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        TEST_SERVICES=\"com.apple.fingerd com.apple.ftp-proxy\"\n        for ITEM in ${TEST_SERVICES}; do\n            if ${LAUNCHCTL_BINARY} list | ${GREPBINARY} -sq ${ITEM}; then\n                Display --indent 2 --text \"- ${ITEM}\" --result \"${STATUS_NO}\" --color RED\n                LogText \"Result: found ${ITEM}, which is considered an insecure service\"\n                ReportSuggestion \"${TEST_NO}\" \"Consider disabling service ${ITEM}\" \"launchctl\" \"-\"\n                AddHP 0 1\n            else\n                Display --indent 2 --text \"- ${ITEM}\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: did not find ${ITEM}, which is fine\"\n                AddHP 1 1\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_kerberos",
    "content": "#!/bin/sh\n\nInsertSection \"${SECTION_KERBEROS}\"\n\n#\n#########################################################################\n#\n\n    # Test        : KRB-1000\n    # Description : Check that Kerberos principals have passwords that expire\n    Register --test-no KRB-1000 --weight L --network NO --description \"Check for Kerberos KDC tools\"\n    if [ -n \"${KADMINLOCALBINARY}\" ] && [ -n \"${KDB5UTILBINARY}\" ]\n    then\n        PREQS_MET=\"YES\"\n        # Make sure krb5 debugging doesn't mess up the output\n        unset KRB5_TRACE\n        PRINCS=\"$(${KADMINLOCALBINARY} listprincs 2>/dev/null | ${TRBINARY:-tr} '\\n' ' ')\"\n        if [ -z \"${PRINCS}\" ]\n        then\n            PREQS_MET=\"NO\"\n        fi\n    else\n        PREQS_MET=\"NO\"\n    fi\n    if [ \"${PREQS_MET}\" = \"YES\" ]; then\n        Display --indent 2 --text \"- Check for Kerberos KDC and principals\" --result \"${STATUS_FOUND}\" --color GREEN\n    else\n        Display --indent 2 --text \"- Check for Kerberos KDC and principals\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n    fi\n\n    # Test        : KRB-1010\n    # Description : Check that Kerberos principals have passwords that expire\n    Register --test-no KRB-1010 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check that Kerberos principals have passwords that expire\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for I in ${PRINCS}\n        do\n            FIND=\"$(${KADMINLOCALBINARY} getprinc \"${I}\" | ${GREPBINARY} '^Password expiration date:')\"\n            if [ \"${FIND}\" = \"Password expiration date: [never]\" ]\n            then\n                LogText \"Result: Kerberos principal ${I} has a password/key that never expires\"\n                FOUND=1\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 4 --text \"- Principals without expiring password\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Make sure all your Kerberos principals have expiring passwords\"\n        else\n            Display --indent 4 --text \"- Principals without expiring password\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n\n    # Test        : KRB-1020\n    # Description : Check last password change for Kerberos principals\n    Register --test-no KRB-1020 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check last password change for Kerberos principals\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for I in ${PRINCS}\n        do\n            FIND=\"$(${KADMINLOCALBINARY} getprinc \"${I}\" | ${SEDBINARY} -n '/^Last password change:\\s\\+/s/^Last password change:\\s\\+//p')\"\n            if [ \"${FIND}\" = \"[never]\" ]\n            then\n                LogText \"Result: Kerberos principal ${I} has a password/key that has never been changed\"\n                FOUND=1\n            else\n                J=\"$(date -d \"${FIND}\" +%s)\"\n                if [ ${J} -lt $((NOW - 60 * 60 * 24 * 365)) ]\n                then\n                    LogText \"Result: Kerberos principal ${I} has had a password/key change over a year ago\"\n                    FOUND=1\n                fi\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 4 --text \"- Principals with late password change\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Enforce frequent password/key change for your Kerberos principals\"\n        else\n            Display --indent 4 --text \"- Principals with late password change\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n\n#\n#################################################################################\n#\n\n    # Test        : KRB-1030\n    # Description : Check that Kerberos principals have a policy associated to them\n    Register --test-no KRB5-1030 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check that Kerberos principals have a policy associated to them\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for I in ${PRINCS}\n        do\n            FIND=\"$(${KADMINLOCALBINARY} getprinc \"${I}\" | ${GREPBINARY} '^Policy:')\"\n            if [ \"${FIND}\" = \"Policy: [none]\" ]\n            then\n                LogText \"Result: Kerberos principal ${I} does not have a policy associated to it\"\n                FOUND=1\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 4 --text \"- Principals without associated policy\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Make sure all your Kerberos principals have a policy associated to them\"\n        else\n            Display --indent 4 --text \"- Principals without associated policy\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n\n#\n#################################################################################\n#\n\n    # Test        : KRB-1040\n    # Description : Check various attributes for Kerberos principals\n    Register --test-no KRB5-1040 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check various attributes for Kerberos principals\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for I in ${PRINCS}\n        do\n            J=\"$(${KADMINLOCALBINARY} getprinc \"${I}\" | ${SEDBINARY} -n 's/^Attributes:\\s\\+\\(.\\+\\)$/\\1/p')\"\n            if ContainsString \"^K/M@\" \"${I}\" || \\\n                ContainsString \"^kadmin/admin@\" \"${I}\" || \\\n                ContainsString \"^kadmin/changepw@\" \"${I}\" || \\\n                ContainsString \"^krbtgt/\" \"${I}\"\n            then\n                if ! ContainsString \"\\bLOCKDOWN_KEYS\\b\" \"${J}\"\n                then\n                    LogText \"Result: Sensitive Kerberos principal ${I} does not have the lockdown_keys attribute\"\n                    FOUND=1\n                fi\n            elif ContainsString \"/admin@\" \"${I}\"\n            then\n                if ! ContainsString \"\\bDISALLOW_TGT_BASED\\b\" \"${J}\"\n                then\n                    LogText \"Result: Kerberos admin principal ${I} does not have the disallow_tgt_based attribute\"\n                    FOUND=1\n                fi\n            elif ContainsString \"^[^/$]+@\" \"${I}\"\n            then\n                if ! ContainsString \"\\bREQUIRES_PRE_AUTH\\b.+\\bDISALLOW_SVR\\b\" \"${J}\"\n                then\n                    LogText \"Result: Regular Kerberos user principal ${I} does not have the requires_pre_auth and/or the disallow_svr attribute\"\n                    FOUND=1\n                fi\n            fi\n        done\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 4 --text \"- Checking principals for various attributes\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Harden your Kerberos principals with appropriate attributes\"\n        else\n            Display --indent 4 --text \"- Checking principals for various attributes\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n\n#\n#################################################################################\n#\n\n    # Test        : KRB-1050\n    # Description : Check for weak crypto\n    Register --test-no KRB-1050 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check for weak crypto\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${KDB5UTILBINARY} tabdump keyinfo | ${AWKBINARY} '$4 ~ /(des|arcfour|cbc|sha1)/{print$1,$4}')\n        if [ -n \"${FIND}\" ]; then\n            while read I J\n            do\n                LogText \"Result: Kerberos principal ${I} has a key with weak cryptographic algorithm ${J}\"\n            done << EOF\n${FIND}\nEOF\n            Display --indent 4 --text \"- Principals with weak crypto\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Remove weak (des|arcfour|cbc|sha1) cryptographic keys from principals\"\n        else\n            Display --indent 4 --text \"- Principals with weak crypto\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n\n#\n#################################################################################\n#\n\nunset PRINCS\nunset I\nunset J\n\n#EOF\n"
  },
  {
    "path": "include/tests_kernel",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Kernel\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_KERNEL}\"\n#\n#################################################################################\n#\n    CPU_PAE=0\n    CPU_NX=0\n    LINUXCONFIGFILE=\"\"\n    LINUXCONFIGFILE_ZIPPED=0\n    LIMITS_DIRECTORY=\"${ROOTDIR}etc/security/limits.d\"\n    APT_ARCHIVE_DIRECTORY=\"${ROOTDIR}var/cache/apt/archives\"\n#\n#################################################################################\n#\n    # Test        : KRNL-5622\n    # Description : Check default run level on Linux machines\n    Register --test-no KRNL-5622 --os Linux --weight L --network NO --category security --description \"Determine Linux default run level\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Checking if we can find the systemd default target\n        LogText \"Test: Checking for systemd default.target\"\n        if [ $( [ ! -z ${SYSTEMCTLBINARY} ] && ${SYSTEMCTLBINARY} get-default) ]; then\n            FIND=$(${SYSTEMCTLBINARY} get-default)\n            FIND2=$(${ECHOCMD} ${FIND} | ${EGREPBINARY} \"runlevel5|graphical\")\n            if HasData \"${FIND2}\"; then\n                LogText \"Result: Found match on runlevel5/graphical\"\n                Display --indent 2 --text \"- Checking default runlevel\" --result \"runlevel 5\" --color GREEN\n                Report \"linux_default_runlevel=5\"\n            else\n                LogText \"Result: No match found on runlevel, defaulting to runlevel 3\"\n                Display --indent 2 --text \"- Checking default runlevel\" --result \"runlevel 3\" --color GREEN\n                Report \"linux_default_runlevel=3\"\n            fi\n        else\n            LogText \"Result: no systemd found, so trying inittab\"\n            LogText \"Test: Checking ${ROOTDIR}etc/inittab\"\n            if [ -f ${ROOTDIR}etc/inittab ]; then\n                LogText \"Result: file ${ROOTDIR}etc/inittab found\"\n                LogText \"Test: Checking default Linux run level\"\n                FIND=$(${AWKBINARY} -F: '/^id/ { print $2; }' ${ROOTDIR}etc/inittab | head -n 1)\n                if IsEmpty \"${FIND}\"; then\n                    Display --indent 2 --text \"- Checking default runlevel\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n                    LogText \"Result: Can't determine default run level from ${ROOTDIR}etc/inittab\"\n                else\n                    Display --indent 2 --text \"- Checking default run level\" --result \"${FIND}\" --color GREEN\n                    LogText \"Found default run level '${FIND}'\"\n                    Report \"linux_default_runlevel=${FIND}\"\n                fi\n            else\n                LogText \"Result: file ${ROOTDIR}etc/inittab not found\"\n                if [ \"${LINUX_VERSION}\" = \"Debian\" ] || [ \"${LINUX_VERSION}\" = \"Ubuntu\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"Debian\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"Ubuntu\" ]; then\n                    LogText \"Test: Checking run level with who -r, for Debian based systems\"\n                    FIND=$(who -r | ${AWKBINARY} '{ if ($1==\"run-level\") { print $2 } }')\n                    if HasData \"${FIND}\"; then\n                        LogText \"Result: Found default run level '${FIND}'\"\n                        Report \"linux_default_runlevel=${FIND}\"\n                        Display --indent 2 --text \"- Checking default run level\" --result \"RUNLEVEL ${FIND}\" --color GREEN\n                    else\n                        LogText \"Result: Can't determine default run level from who -r\"\n                        Display --indent 2 --text \"- Checking default run level\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n                    fi\n                fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5677\n    # Description : Check CPU options and support (PAE, No eXecute, eXecute Disable)\n    # More info   : pae and nx bit are both visible on AMD and Intel CPU's if supported\n\n    Register --test-no KRNL-5677 --platform \"x86_64 amd64\" --os \"Linux NetBSD\" --weight L --network NO --category security --description \"Check CPU options and support\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking CPU support (NX/PAE)\"\n        LogText \"Test: Checking /proc/cpuinfo\"\n        if [ -f /proc/cpuinfo ]; then\n            LogText \"Result: found /proc/cpuinfo\"\n            LogText \"Test: Checking CPU options (XD/NX/PAE)\"\n            FIND_PAE_NX=$(${GREPBINARY} \" pae \" /proc/cpuinfo | ${GREPBINARY} \" nx \")\n            FIND_PAE=$(${GREPBINARY} \" pae \" /proc/cpuinfo)\n            FIND_NX=$(${GREPBINARY} \" nx \" /proc/cpuinfo)\n            FOUND=0\n            if HasData \"${FIND_PAE_NX}\"; then\n                LogText \"PAE: Yes\"\n                LogText \"NX: Yes\"\n                CPU_PAE=1\n                CPU_NX=1\n                LogText \"Result: PAE or No eXecute option(s) both found\"\n                Report \"cpu_pae=1\"\n                Report \"cpu_nx=1\"\n                FOUND=1\n            else\n                if HasData \"${FIND_PAE}\" && IsEmpty \"${FIND_NX}\"; then\n                    Report \"cpu_pae=1\"\n                    LogText \"Result: found PAE\"\n                    CPU_PAE=1\n                    FOUND=1\n                else\n                    if HasData \"${FIND_NX}\" && IsEmpty \"${FIND_PAE}\"; then\n                        Report \"cpu_nx=1\"\n                        LogText \"Result: found No eXecute\"\n                        CPU_NX=1\n                        FOUND=1\n                    else\n                        LogText \"Result: found no CPU options enabled (PAE or NX bit)\"\n                    fi\n                fi\n            fi\n            if [ ${FOUND} -eq 1 ]; then\n                Display --indent 4 --text \"CPU support: PAE and/or NoeXecute supported\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                Display --indent 4 --text \"CPU support: No PAE or NoeXecute supported\" --result \"${STATUS_NONE}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Use a PAE enabled kernel when possible to gain native No eXecute/eXecute Disable support\"\n            fi\n        else\n            Display --indent 4 --text \"CPU support: no /proc/cpuinfo\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n            LogText \"Result: /proc/cpuinfo not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5680\n    # Description : Check if installed kernel has PAE support\n    # Dependency  : KRNL-5677\n    # More info   : RedHat/CentOS/Fedora uses the package name 'kernel-PAE'\n#\n#################################################################################\n#\n    # Test        : KRNL-5695\n    # Description : Determining Linux kernel version and release number\n    Register --test-no KRNL-5695 --os Linux --weight L --network NO --category security --description \"Determine Linux kernel version and release number\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Kernel number (and suffix)\n        LINUX_KERNEL_RELEASE=$(uname -r)\n        Report \"linux_kernel_release=${LINUX_KERNEL_RELEASE}\"\n        LogText \"Result: found kernel release ${LINUX_KERNEL_RELEASE}\"\n        # Type and build date\n        LINUX_KERNEL_VERSION=$(uname -v)\n        Report \"linux_kernel_version=${LINUX_KERNEL_VERSION}\"\n        LogText \"Result: found kernel version ${LINUX_KERNEL_VERSION}\"\n        Display --indent 2 --text \"- Checking kernel version and release\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5723\n    # Description : Check if Linux is build as a monolithic kernel or not\n    Register --test-no KRNL-5723 --os Linux --weight L --network NO --category security --description \"Determining if Linux kernel is monolithic\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${LSMODBINARY}\" -a -f /proc/modules ]; then\n            LogText \"Test: checking if kernel is monolithic or modular\"\n            # Checking if any modules are loaded\n            FIND=$(${LSMODBINARY} | ${GREPBINARY} -v \"^Module\" | wc -l | ${TRBINARY} -s ' ' | ${TRBINARY} -d ' ')\n            Display --indent 2 --text \"- Checking kernel type\" --result \"${STATUS_DONE}\" --color GREEN\n            MONOLITHIC_KERNEL_TESTED=1\n            if [ \"${FIND}\" = \"0\" ]; then\n                LogText \"Result: Found monolithic kernel\"\n                Report \"linux_kernel_type=monolithic\"\n                MONOLITHIC_KERNEL=1\n            else\n                LogText \"Result: Found modular kernel\"\n                Report \"linux_kernel_type=modular\"\n                MONOLITHIC_KERNEL=0\n            fi\n        else\n            LogText \"Test skipped, lsmod binary not found or /proc/modules can not be opened\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5726\n    # Description : Checking Linux loaded kernel modules\n    Register --test-no KRNL-5726 --os Linux --weight L --network NO --category security --description \"Checking Linux loaded kernel modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${LSMODBINARY}\" -a -f /proc/modules ]; then\n            FIND=$(${LSMODBINARY} | ${AWKBINARY} '{ if ($1!=\"Module\") print $1 }' | sort)\n            Display --indent 2 --text \"- Checking loaded kernel modules\" --result \"${STATUS_DONE}\" --color GREEN\n            if HasData \"${FIND}\"; then\n                LogText \"Loaded modules according lsmod:\"\n                COUNT=0\n                for ITEM in ${FIND}; do\n                    LogText \"Loaded module: ${ITEM}\"\n                    Report \"loaded_kernel_module[]=${ITEM}\"\n                    COUNT=$((COUNT + 1))\n                done\n                Display --indent 6 --text \"Found ${COUNT} active modules\"\n            else\n                LogText \"Result: no loaded modules found\"\n                LogText \"Notice: No loaded kernel modules could indicate a broken/malformed lsmod, or a (custom) monolithic kernel\"\n            fi\n        else\n            LogText \"Test skipped, lsmod binary not found or /proc/modules can not be opened\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5728\n    # Description : Checking for available Linux kernel configuration file in /boot\n    Register --test-no KRNL-5728 --os Linux --weight L --network NO --category security --description \"Checking Linux kernel config\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        CHECKFILE=\"${ROOTDIR}boot/config-$(uname -r)\"\n        CHECKFILE_ZIPPED=\"${ROOTDIR}proc/config.gz\"\n        if [ -f ${CHECKFILE} ]; then\n            LINUXCONFIGFILE=\"${CHECKFILE}\"\n            LogText \"Result: found config (${LINUXCONFIGFILE})\"\n            Display --indent 2 --text \"- Checking Linux kernel configuration file\" --result \"${STATUS_FOUND}\" --color GREEN\n        elif [ -f ${CHECKFILE_ZIPPED} ]; then\n            LINUXCONFIGFILE=\"${CHECKFILE_ZIPPED}\"\n            LINUXCONFIGFILE_ZIPPED=1\n            LogText \"Result: found config: ${ROOTDIR}proc/config.gz (compressed)\"\n            Display --indent 2 --text \"- Checking Linux kernel configuration file\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: no Linux kernel configuration file found in ${ROOTDIR}boot\"\n            Display --indent 2 --text \"- Checking Linux kernel configuration file\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n        if HasData \"${LINUXCONFIGFILE}\"; then\n            Report \"linux_config_file=${LINUXCONFIGFILE}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5730\n    # Description : Checking default I/O kernel scheduler\n    # Notes       : This test could be extended with testing some of the specific devices like disks\n    #               cat /sys/block/sda/queue/scheduler\n    PREQS_MET=\"NO\"\n    if HasData \"${LINUXCONFIGFILE}\"; then\n        if [ -f ${LINUXCONFIGFILE} ]; then PREQS_MET=\"YES\"; fi\n    fi\n    Register --test-no KRNL-5730 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking disk I/O kernel scheduler\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${LINUXCONFIGFILE_ZIPPED} -eq 1 ]; then GREPTOOL=\"${ZGREPBINARY}\"; else GREPTOOL=\"${GREPBINARY}\"; fi\n        if [ -n \"${GREPTOOL}\" ]; then\n            LogText \"Test: Checking the default I/O kernel scheduler\"\n            LINUX_KERNEL_IOSCHED=$(${GREPTOOL} \"CONFIG_DEFAULT_IOSCHED\" ${LINUXCONFIGFILE} | ${AWKBINARY} -F= '{ print $2 }' | ${SEDBINARY} s/\\\"//g)\n            if [ -n \"${LINUX_KERNEL_IOSCHED}\" ]; then\n                LogText \"Result: found IO scheduler '${LINUX_KERNEL_IOSCHED}'\"\n                Display --indent 2 --text \"- Checking default I/O kernel scheduler\" --result \"${STATUS_FOUND}\" --color GREEN\n                Report \"linux_kernel_io_scheduler[]=${LINUX_KERNEL_IOSCHED}\"\n            else\n                LogText \"Result: no default I/O kernel scheduler found\"\n                Display --indent 2 --text \"- Checking default I/O kernel scheduler\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            fi\n        else\n            ReportException \"${TEST_NO}\" \"No valid ${GREPBINARY} tool found to search kernel settings\"\n        fi\n   fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5745\n    # Description : Checking FreeBSD loaded kernel modules\n    Register --test-no KRNL-5745 --os FreeBSD --weight L --network NO --category security --description \"Checking FreeBSD loaded kernel modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking active kernel modules\"\n        LogText \"Test: Active kernel modules (KLDs)\"\n        LogText \"Description: View all active kernel modules (including kernel)\"\n        LogText \"Test: Checking modules\"\n        if [ -f /sbin/kldstat ]; then\n            FIND=$(kldstat | ${GREPBINARY} -v 'Name' | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f6)\n            if [ $? -eq 0 ]; then\n                LogText \"Loaded modules according kldstat:\"\n                COUNT=0\n                for ITEM in ${FIND}; do\n                    LogText \"Loaded module: ${ITEM}\"\n                    Report \"loaded_kernel_module[]=${ITEM}\"\n                    COUNT=$((COUNT + 1))\n                done\n                Display --indent 4 --text \"Found ${COUNT} kernel modules\" --result \"${STATUS_DONE}\" --color GREEN\n            else\n                Display --indent 4 --text \"Test failed\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: Problem with executing kldstat\"\n            fi\n        else\n            LogText \"Result: no results, can't find /sbin/kldstat\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5831\n    # Description : Checking DragonFly loaded kernel modules\n    Register --test-no KRNL-5831 --os DragonFly --weight L --network NO --category security --description \"Checking DragonFly loaded kernel modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking active kernel modules\"\n        LogText \"Test: Active kernel modules (KLDs)\"\n        LogText \"Description: View all active kernel modules (including kernel)\"\n        LogText \"Test: Checking modules\"\n        if [ -x /sbin/kldstat ]; then\n            FIND=$(/sbin/kldstat | ${GREPBINARY} -v 'Name' | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f6)\n            if [ $? -eq 0 ]; then\n                LogText \"Loaded modules according kldstat:\"\n                COUNT=0\n                for ITEM in ${FIND}; do\n                    LogText \"Loaded module: ${ITEM}\"\n                    Report \"loaded_kernel_module[]=${ITEM}\"\n                    COUNT=$((COUNT + 1))\n                done\n                Display --indent 4 --text \"Found ${COUNT} kernel modules\" --result \"${STATUS_DONE}\" --color GREEN\n            else\n                Display --indent 4 --text \"Test failed\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: Problem with executing kldstat\"\n            fi\n        else\n            echo \"[ ${WHITE}SKIPPED${NORMAL} ]\"\n            LogText \"Result: no results, can NOT find /sbin/kldstat\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5770\n    # Description : Checking Solaris load modules\n    Register --test-no KRNL-5770 --os Solaris --weight L --network NO --category security --description \"Checking active kernel modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching loaded kernel modules\"\n        FIND=$(/usr/sbin/modinfo -c -w | ${GREPBINARY} -v \"UNLOADED\" | ${GREPBINARY} LOADED | ${AWKBINARY} '{ print $3 }' | sort)\n        if HasData \"${FIND}\"; then\n            for ITEM in ${FIND}; do\n                LogText \"Found module: ${ITEM}\"\n                Report \"loaded_kernel_module[]=${ITEM}\"\n            done\n            Display --indent 2 --text \"- Checking Solaris active kernel modules\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            LogText \"Result: no output\"\n            Display --indent 2 --text \"- Checking Solaris active kernel modules\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5788\n    # Description : Checking availability new kernel\n    if [ \"${LINUX_VERSION}\" = \"Debian\" ] || [ \"${LINUX_VERSION}\" = \"Ubuntu\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"Debian\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"Ubuntu\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n    Register --test-no KRNL-5788 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking availability new Linux kernel\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FINDKERNEL=\"\"\n        HAS_VMLINUZ=0\n        LogText \"Test: Searching apt-cache, to determine if a newer kernel is available\"\n        if [ -x ${ROOTDIR}usr/bin/apt-cache ]; then\n            LogText \"Result: found ${ROOTDIR}usr/bin/apt-cache\"\n            LogText \"Test: checking presence of ${ROOTDIR}vmlinuz or ${ROOTDIR}boot/vmlinuz\"\n            if [ -f ${ROOTDIR}vmlinuz -o -f ${ROOTDIR}boot/vmlinuz ]; then\n                HAS_VMLINUZ=1\n                if [ -f ${ROOTDIR}vmlinuz ]; then\n                    FINDVMLINUZ=\"${ROOTDIR}vmlinuz\"\n                else\n                    FINDVMLINUZ=\"${ROOTDIR}boot/vmlinuz\"\n                fi\n                LogText \"Result: found ${FINDVMLINUZ}\"\n                LogText \"Test: checking readlink location of ${FINDVMLINUZ}\"\n                FINDKERNFILE=$(readlink -f ${FINDVMLINUZ})\n                LogText \"Output: readlink reported file ${FINDKERNFILE}\"\n                LogText \"Test: checking relevant package using output from dpkg -S\"\n                FINDKERNEL=$(dpkg -S ${FINDKERNFILE} 2> /dev/null | ${AWKBINARY} -F : '{print $1}')\n                LogText \"Output: dpkg -S reported package ${FINDKERNEL}\"\n            elif [ -e ${ROOTDIR}dev/grsec ]; then\n                FINDKERNEL=\"linux-image-$(uname -r)\"\n                LogText \"Result: ${ROOTDIR}vmlinuz missing due to grsecurity; assuming ${FINDKERNEL}\"\n            elif [ -e ${ROOTDIR}etc/rpi-issue ]; then\n                FINDKERNEL=\"raspberrypi-kernel\"\n                LogText \"Result: ${ROOTDIR}vmlinuz missing due to Raspbian\"\n            elif $(${GREPBINARY} -E -q 'do_symlinks.*=.*No' ${ROOTDIR}etc/kernel-img.conf); then\n                FINDKERNEL=\"linux-image-$(uname -r)\"\n                LogText \"Result: ${ROOTDIR}vmlinuz missing due to /etc/kernel-img.conf item do_symlinks = No\"\n            else\n                LogText \"This system is missing ${ROOTDIR}vmlinuz or ${ROOTDIR}boot/vmlinuz. Unable to check whether kernel is up-to-date.\"\n                ReportSuggestion \"${TEST_NO}\" \"Determine why ${ROOTDIR}vmlinuz or ${ROOTDIR}boot/vmlinuz is missing on this Debian/Ubuntu system.\" \"/vmlinuz or /boot/vmlinuz\"\n            fi\n\n            if IsEmpty \"${FINDKERNEL}\"; then\n                LogText \"Result: could not check kernel update status as kernel is unknown\"\n            else\n                LogText \"Result: found kernel '${FINDKERNEL}' which will be used for further testing\"\n                LogText \"Test: Using apt-cache policy to determine if there is an update available\"\n                FINDINSTALLED=$(apt-cache policy ${FINDKERNEL} | ${GREPBINARY} -E 'Installed' | ${CUTBINARY} -d ':' -f2 | ${TRBINARY} -d ' ')\n                FINDCANDIDATE=$(apt-cache policy ${FINDKERNEL} | ${GREPBINARY} -E 'Candidate' | ${CUTBINARY} -d ':' -f2 | ${TRBINARY} -d ' ')\n                LogText \"Kernel installed: ${FINDINSTALLED}\"\n                LogText \"Kernel candidate: ${FINDCANDIDATE}\"\n                if IsEmpty \"${FINDINSTALLED}\"; then\n                    Display --indent 2 --text \"- Checking for available kernel update\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n                    LogText \"Result: Exception occurred, no output from apt-cache policy\"\n                    if [ ${HAS_VMLINUZ} -eq 1 ]; then\n                        ReportException \"${TEST_NO}:01\" \"Found vmlinuz (${FINDVMLINUZ}) but could not determine the installed kernel using apt-cache policy\"\n                        ReportSuggestion \"${TEST_NO}\" \"Check the output of apt-cache policy to determine why its output is empty\"\n                    fi\n                    LogText \"Result: apt-cache policy did not return an installed kernel version\"\n                else\n                    if [ \"${FINDINSTALLED}\" = \"${FINDCANDIDATE}\" ]; then\n                        if [ -e /dev/grsec ]; then\n                            Display --indent 2 --text \"- Checking for available kernel update\" --result GRSEC --color GREEN\n                            LogText \"Result: Grsecurity is installed; unable to determine if there's a newer kernel available\"\n                            ReportManual \"Manually check to confirm you're using a recent kernel and grsecurity patch\"\n                        else\n                            Display --indent 2 --text \"- Checking for available kernel update\" --result \"${STATUS_OK}\" --color GREEN\n                            LogText \"Result: no kernel update available\"\n                        fi\n                    else\n                        Display --indent 2 --text \"- Checking for available kernel update\" --result \"UPDATE AVAILABLE\" --color YELLOW\n                        LogText \"Result: kernel update available according 'apt-cache policy'.\"\n                        ReportSuggestion \"${TEST_NO}\" \"Determine priority for available kernel update\"\n                    fi\n                fi\n            fi\n        else\n            LogText \"Result: could NOT find ${ROOTDIR}usr/bin/apt-cache, skipped other tests.\"\n        fi\n        unset FINDCANDIDATE FINDINSTALLED FINDKERNEL HAS_VMLINUZ\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5820\n    # Description : Checking core dumps configuration (Linux)\n    Register --test-no KRNL-5820 --os Linux --weight L --network NO --category security --description \"Checking core dumps configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking core dumps configuration\"\n        LogText \"Test: Checking presence of systemd\"\n        # systemd option\n        if [ $HAS_SYSTEMD -eq 1 ]; then\n            LogText \"Result: systemd is present on this system\"\n            LogText \"Test: Checking if core dumps are disabled in ${ROOTDIR}etc/systemd/coredump.conf and ${ROOTDIR}etc/systemd/coredump.conf.d/*.conf\"\n            # check likely main config file for systemd: ${ROOTDIR}etc/systemd/coredump.conf for ProcessSizeMax=0 and Storage=none\n            SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED=$(${GREPBINARY} -v \"^ *#\" ${ROOTDIR}etc/systemd/coredump.conf 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -i \"^ProcessSizeMax=\" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\\([A-Z][a-z]*\\)*$//g' | ${GREPBINARY} \"^0 *$\" | ${WCBINARY} -l)\n            SYSD_CORED_BASE_PROCSIZEMAX_NR_ENABLED=$(${GREPBINARY} -v \"^ *#\" ${ROOTDIR}etc/systemd/coredump.conf 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -i \"^ProcessSizeMax=\" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\\([A-Z][a-z]*\\)*$//g' | ${GREPBINARY} -v \"^0 *$\" | ${WCBINARY} -l)\n            SYSD_CORED_BASE_STORAGE_FOUND=$(${GREPBINARY} -v \"^ *#\" ${ROOTDIR}etc/systemd/coredump.conf 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -i \"^Storage=\" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g')\n            SYSD_CORED_BASE_STORAGE_NR_ENABLED=$(${ECHOCMD} \"${SYSD_CORED_BASE_STORAGE_FOUND}\" | ${SEDBINARY} 's/none//g' | ${WCBINARY} | ${AWKBINARY} '{print $2}')\n            SYSD_CORED_BASE_STORAGE_NR_DISABLED=$(${ECHOCMD} \"${SYSD_CORED_BASE_STORAGE_FOUND}\" | ${GREPBINARY} -o \"none\" | ${WCBINARY} | ${AWKBINARY} '{print $2}')\n            # check conf files in possibly existing coredump.conf.d folders\n            # using find instead of grep -r to stay POSIX compliant. On AIX and HPUX grep -r is not available.\n            # while there could be multiple files overwriting each other, we are checking the number of occurrences\n            SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED=$(${FINDBINARY} -L /etc/systemd/coredump.conf.d/ /run/systemd/coredump.conf.d/ /usr/lib/systemd/coredump.conf.d/ -type f -iname \"*.conf\" -exec ${SEDBINARY} 's/^ *//g' {} \\; 2> /dev/null | ${GREPBINARY} -i \"^ProcessSizeMax=\" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\\([A-Z][a-z]*\\)*$//g' | ${GREPBINARY} \"^0 *$\" | ${WCBINARY} -l)\n            SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED=$(${FINDBINARY} -L /etc/systemd/coredump.conf.d/ /run/systemd/coredump.conf.d/ /usr/lib/systemd/coredump.conf.d/ -type f -iname \"*.conf\" -exec ${SEDBINARY} 's/^ *//g' {} \\; 2> /dev/null | ${GREPBINARY} -i \"^ProcessSizeMax=\" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g ; s/\\([A-Z][a-z]*\\)*$//g' | ${GREPBINARY} -v \"^0 *$\" | ${WCBINARY} -l)\n            SYSD_CORED_SUB_STORAGE_FOUND=$(${FINDBINARY} -L /etc/systemd/coredump.conf.d/ /run/systemd/coredump.conf.d/ /usr/lib/systemd/coredump.conf.d/ -type f -iname \"*.conf\" -exec ${SEDBINARY} 's/^ *//g' {} \\; 2> /dev/null | ${GREPBINARY} -i \"^Storage=\" | ${CUTBINARY} -d'=' -f2 | ${SEDBINARY} 's/ .*$//g')\n            SYSD_CORED_SUB_STORAGE_NR_ENABLED=$(${ECHOCMD} \"${SYSD_CORED_SUB_STORAGE_FOUND}\" | ${SEDBINARY} 's/none//g' | ${WCBINARY} | ${AWKBINARY} '{print $2}')\n            SYSD_CORED_SUB_STORAGE_NR_DISABLED=$(${ECHOCMD} \"${SYSD_CORED_SUB_STORAGE_FOUND}\" | ${GREPBINARY} -o \"none\" | ${WCBINARY} | ${AWKBINARY} '{print $2}')\n            if ( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ) || \\\n               ( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ) || \\\n               ( [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ) || \\\n               ( [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -eq 0 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -eq 0 ] ); then\n                LogText \"Result: core dumps are disabled by 'ProcessSizeMax=0' and 'Storage=none' in systemd configuration files\"\n                AddHP 1 1\n                TMP_COLOR=\"GREEN\"\n                if [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -gt 1 ] || [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -gt 1 ] || [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_DISABLED} -gt 1 ] || [ ${SYSD_CORED_SUB_STORAGE_NR_DISABLED} -gt 1 ]; then\n                    LogText \"Result: 'ProcessSizeMax=0' and 'Storage=none' are set multiple times in systemd configuration files. Check config!\"\n                    ReportSuggestion \"${TEST_NO}\" \"Check systemd configuration for duplicate entries of core dump settings\"\n                    TMP_COLOR=\"YELLOW\"\n                fi\n                Display --indent 4 --text \"- configuration in systemd conf files\" --result \"${STATUS_DISABLED}\" --color \"${TMP_COLOR}\"\n            elif [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_DISABLED} -ge 1 ] && [ ${SYSD_CORED_BASE_STORAGE_NR_DISABLED} -ge 1 ] && ( [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -ge 1 ] || [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -ge 1 ] ); then\n                LogText \"Result: 'ProcessSizeMax=0' and 'Storage=none' are set in ${ROOTDIR}etc/systemd/coredump.conf but overwritten in subdir config files\"\n                ReportSuggestion \"${TEST_NO}\" \"Check systemd configuration for overwriting core dump settings\"\n                Display --indent 4 --text \"- configuration in systemd conf files\" --result \"${STATUS_ENABLED}\" --color YELLOW\n                AddHP 0 1\n            elif ( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_BASE_STORAGE_NR_ENABLED} -ge 1 ] ) || \\\n                 ( [ ${SYSD_CORED_BASE_PROCSIZEMAX_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -ge 1 ] ) || \\\n                 ( [ ${SYSD_CORED_BASE_STORAGE_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -ge 1 ] ) || \\\n                 ( [ ${SYSD_CORED_SUB_PROCSIZEMAX_NR_ENABLED} -ge 1 ] && [ ${SYSD_CORED_SUB_STORAGE_NR_ENABLED} -ge 1 ] ); then\n                LogText \"Result: core dumps are explicitly enabled in systemd configuration files\"\n                ReportSuggestion \"${TEST_NO}\" \"If not required, consider explicit disabling of core dump in ${ROOTDIR}etc/systemd/coredump.conf ('ProcessSizeMax=0', 'Storage=none')\"\n                Display --indent 4 --text \"- configuration in systemd conf files\" --result \"${STATUS_ENABLED}\" --color RED\n                AddHP 0 1\n            else\n                LogText \"Result: core dumps are not disabled in systemd configuration. Didn't find settings 'ProcessSizeMax=0' and 'Storage=none'\"\n                Display --indent 4 --text \"- configuration in systemd conf files\" --result \"${STATUS_DEFAULT}\" --color WHITE\n                AddHP 0 1\n            fi\n        fi\n        # Profile option\n        LogText \"Test: Checking presence ${ROOTDIR}etc/profile\"\n        if [ -f \"${ROOTDIR}etc/profile\" ]; then\n            LogText \"Test: Checking if 'ulimit -c 0' exists in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh\"\n            # use tail -1 in the following commands to get the last entry, which is the one that counts (in case of profile.d/ probably counts)\n            ULIMIT_C_VALUE=\"$(${GREPBINARY} \"ulimit -H\\?c \" ${ROOTDIR}etc/profile 2> /dev/null | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -v \"^#\" | ${TAILBINARY} -1 | ${CUTBINARY} -d' ' -f3 | ${SEDBINARY} 's/ .*$//g ; s/\\([A-Z][a-z]*\\)*$//g')\"\n            ULIMIT_C_VALUE_SUB=\"$(${FINDBINARY} -L ${ROOTDIR}etc/profile.d -name \"*.sh\" -type f -exec ${CAT_BINARY} {} \\; 2> /dev/null | ${GREPBINARY} \"ulimit -H\\?c \" | ${SEDBINARY} 's/^ *//g' | ${GREPBINARY} -v \"^#\" | ${TAILBINARY} -1 | ${CUTBINARY} -d' ' -f3 | ${SEDBINARY} 's/ .*$//g ; s/\\([A-Z][a-z]*\\)*$//g')\"\n            if ( [ -n \"${ULIMIT_C_VALUE_SUB}\" ] && [ \"${ULIMIT_C_VALUE_SUB}\" = \"0\" ] ) || ( [ -n \"${ULIMIT_C_VALUE}\" ] && [ -z \"${ULIMIT_C_VALUE_SUB}\" ] && [ \"${ULIMIT_C_VALUE}\" = \"0\" ] ); then\n                LogText \"Result: core dumps are disabled by 'ulimit -c 0' in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh\"\n                Display --indent 4 --text \"- configuration in etc/profile\" --result \"${STATUS_DISABLED}\" --color GREEN\n                AddHP 1 1\n            elif [ -z \"${ULIMIT_C_VALUE_SUB}\" ] && [ -z \"${ULIMIT_C_VALUE}\" ]; then\n                LogText \"Result: core dumps are not disabled in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh config files. Didn't find setting 'ulimit -c 0'\"\n                Display --indent 4 --text \"- configuration in ${ROOTDIR}etc/profile\" --result \"${STATUS_DEFAULT}\" --color WHITE\n                AddHP 0 1\n            elif ( [ -n \"${ULIMIT_C_VALUE_SUB}\" ] && ( [ \"${ULIMIT_C_VALUE_SUB}\" = \"unlimited\" ] || [ \"${ULIMIT_C_VALUE_SUB}\" != \"0\" ] ) ) || ( [ -n \"${ULIMIT_C_VALUE}\" ] && [ -z \"${ULIMIT_C_VALUE_SUB}\" ] && ( [ \"${ULIMIT_C_VALUE}\" = \"unlimited\" ] || [ \"${ULIMIT_C_VALUE}\" != \"0\" ] ) ); then\n                LogText \"Result: core dumps are enabled in ${ROOTDIR}etc/profile or ${ROOTDIR}etc/profile.d/*.sh config files. A value higher than 0 is configured for 'ulimit -c'\"\n                Display --indent 4 --text \"- configuration in ${ROOTDIR}etc/profile\" --result \"${STATUS_ENABLED}\" --color RED\n                AddHP 0 1\n            else\n                LogText \"Result: ERROR - something went wrong. Unexpected result during check of ${ROOTDIR}etc/profile and ${ROOTDIR}etc/profile.d/*.sh config files. Please report on Github!\"\n                Display --indent 4 --text \"- configuration in ${ROOTDIR}etc/profile\" --result \"${STATUS_ERROR}\" --color YELLOW\n            fi\n        fi\n\n        # Limits options\n        for DIR in \"/\" \"/usr/\"; do\n            LogText \"Test: Checking presence ${DIR}etc/security/limits.conf\"\n            if [ -f \"${DIR}etc/security/limits.conf\" ]; then\n                LogText \"Result: file ${DIR}etc/security/limits.conf exists\"\n                LogText \"Test: Checking if core dumps are disabled in ${DIR}etc/security/limits.conf and ${LIMITS_DIRECTORY}/*\"\n                # using find instead of grep -r to stay POSIX compliant. On AIX and HPUX grep -r is not available.\n                FIND1=$(${FINDBINARY} -L \"${DIR}etc/security/limits.conf\" \"${LIMITS_DIRECTORY}\" -type f -exec ${CAT_BINARY} {} \\; 2> /dev/null | ${GREPBINARY} -v \"^$\" | ${AWKBINARY} '{ if ($1==\"*\" && $2==\"soft\" && $3==\"core\" && $4==\"0\") { print \"soft core disabled\" } else if ($1==\"*\" && $2==\"soft\" && $3==\"core\" && $4!=\"0\") { print \"soft core enabled\" } }' | ${TAILBINARY} -1)\n                FIND2=$(${FINDBINARY} -L \"${DIR}etc/security/limits.conf\" \"${LIMITS_DIRECTORY}\" -type f -exec ${CAT_BINARY} {} \\; 2> /dev/null | ${GREPBINARY} -v \"^$\" | ${AWKBINARY} '{ if ($1==\"*\" && $2==\"hard\" && $3==\"core\" && $4==\"0\") { print \"hard core disabled\" } else if ($1==\"*\" && $2==\"hard\" && $3==\"core\" && $4!=\"0\") { print \"hard core enabled\" } }' | ${TAILBINARY} -1)\n                FIND3=$(${FINDBINARY} -L \"${DIR}etc/security/limits.conf\" \"${LIMITS_DIRECTORY}\" -type f -exec ${CAT_BINARY} {} \\; 2> /dev/null | ${GREPBINARY} -v \"^$\" | ${AWKBINARY} '{ if ($1==\"*\" && $2==\"-\" && $3==\"core\" && $4==\"0\") { print \"core dumps disabled\" } else if ($1==\"*\" && $2==\"-\" && $3==\"core\" && $4!=\"0\") { print \"core dumps enabled\" } }' | ${TAILBINARY} -1)\n\n                # When \"* - core [value]\" is used, then this sets both soft and core. In that case we set the values, as they the type 'hard' and 'soft' will not be present in the configuration file.\n                if [ \"${FIND3}\" = \"core dumps disabled\" ]; then\n                    FIND1=\"soft core disabled\"\n                    FIND2=\"hard core disabled\"\n                elif [ \"${FIND3}\" = \"core dumps enabled\" ]; then\n                    FIND1=\"soft core enabled\"\n                    FIND2=\"hard core enabled\"\n                fi\n\n                IS_SOFTCORE_DISABLED=\"$(if [ \"${FIND1}\" = \"soft core disabled\" ]; then ${ECHOCMD} DISABLED; elif [ \"${FIND1}\" = \"soft core enabled\" ]; then ${ECHOCMD} ENABLED; else ${ECHOCMD} ${STATUS_DEFAULT}; fi)\"\n                IS_HARDCORE_DISABLED=\"$(if [ \"${FIND2}\" = \"hard core disabled\" ]; then ${ECHOCMD} DISABLED; elif [ \"${FIND2}\" = \"hard core enabled\" ]; then ${ECHOCMD} ENABLED; else ${ECHOCMD} ${STATUS_DEFAULT}; fi)\"\n\n                if [ \"${FIND2}\" = \"hard core disabled\" ]; then\n                    LogText \"Result: core dumps are hard disabled\"\n                    Display --indent 4 --text \"- 'hard' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_HARDCORE_DISABLED}\" --color \"GREEN\"\n                    if [ \"${FIND1}\" = \"soft core disabled\" ]; then\n                        Display --indent 4 --text \"- 'soft' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_SOFTCORE_DISABLED}\" --color \"GREEN\"\n                    else\n                        Display --indent 4 --text \"- 'soft' config in ${DIR}etc/security/limits.conf (implicit)\" --result \"${STATUS_DISABLED}\" --color \"GREEN\"\n                    fi\n                    AddHP 3 3\n                elif [ \"${FIND1}\" = \"soft core enabled\" ] && [ \"${FIND2}\" = \"hard core enabled\" ]; then\n                    LogText \"Result: core dumps (soft and hard) are enabled\"\n                    Display --indent 4 --text \"- 'hard' configuration in ${DIR}etc/security/limits.conf\" --result \"${STATUS_ENABLED}\" --color \"RED\"\n                    Display --indent 4 --text \"- 'soft' configuration in ${DIR}etc/security/limits.conf\" --result \"${STATUS_ENABLED}\" --color \"RED\"\n                    ReportSuggestion \"${TEST_NO}\" \"If not required, consider explicit disabling of core dump in /etc/security/limits.conf file\"\n                    AddHP 0 3\n                elif [ \"${FIND1}\" = \"soft core disabled\" ]; then\n                    LogText \"Result: core dumps are disabled for 'soft' ('hard'=${IS_HARDCORE_DISABLED})\"\n                    Display --indent 4 --text \"- 'hard' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_HARDCORE_DISABLED}\" --color \"$(if [ \"${IS_HARDCORE_DISABLED}\" = \"ENABLED\" ]; then ${ECHOCMD} RED; elif [ \"${IS_HARDCORE_DISABLED}\" = \"DISABLED\" ]; then ${ECHOCMD} GREEN; else ${ECHOCMD} WHITE; fi)\"\n                    Display --indent 4 --text \"- 'soft' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_SOFTCORE_DISABLED}\" --color \"GREEN\"\n                    AddHP 2 3\n                elif [ \"${FIND1}\" = \"soft core enabled\" ] || [ \"${FIND2}\" = \"hard core enabled\" ]; then\n                    LogText \"Result: core dumps are partially enabled ('hard'=${IS_HARDCORE_DISABLED}, 'soft'=${IS_SOFTCORE_DISABLED})\"\n                    Display --indent 4 --text \"- 'hard' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_HARDCORE_DISABLED}\" --color \"$(if [ \"${IS_HARDCORE_DISABLED}\" = \"ENABLED\" ]; then ${ECHOCMD} RED; elif [ \"${IS_HARDCORE_DISABLED}\" = \"DISABLED\" ]; then ${ECHOCMD} GREEN; else ${ECHOCMD} WHITE; fi)\"\n                    Display --indent 4 --text \"- 'soft' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_SOFTCORE_DISABLED}\" --color \"$(if [ \"${IS_SOFTCORE_DISABLED}\" = \"ENABLED\" ]; then ${ECHOCMD} RED; elif [ \"${IS_SOFTCORE_DISABLED}\" = \"DISABLED\" ]; then ${ECHOCMD} GREEN; else ${ECHOCMD} WHITE; fi)\"\n                    AddHP 0 3\n                else\n                    LogText \"Result: core dumps are not explicitly disabled\"\n                    Display --indent 4 --text \"- 'hard' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_HARDCORE_DISABLED}\" --color \"WHITE\"\n                    Display --indent 4 --text \"- 'soft' configuration in ${DIR}etc/security/limits.conf\" --result \"${IS_HARDCORE_DISABLED}\" --color \"WHITE\"\n                    ReportSuggestion \"${TEST_NO}\" \"If not required, consider explicit disabling of core dump in ${DIR}etc/security/limits.conf file\"\n                    AddHP 1 3\n                fi\n            else\n                LogText \"Result: file ${DIR}etc/security/limits.conf does not exist, skipping test for this file\"\n            fi\n        done\n\n        # Sysctl option\n        LogText \"Test: Checking sysctl value of fs.suid_dumpable\"\n        FIND=$(${SYSCTLBINARY} fs.suid_dumpable 2> /dev/null | ${AWKBINARY} '{ if ($1==\"fs.suid_dumpable\") { print $3 } }')\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: sysctl key fs.suid_dumpable not found\"\n        else\n            LogText \"Result: value ${FIND} found\"\n        fi\n        if [ \"${FIND}\" = \"2\" ]; then\n            LogText \"Result: programs can dump core dump, but only readable by root (value 2, for debugging with file protection)\"\n            Display --indent 4 --text \"- Checking setuid core dumps configuration\" --result \"${STATUS_PROTECTED}\" --color WHITE\n            AddHP 1 1\n        elif [ \"${FIND}\" = \"1\" ]; then\n            LogText \"Result: all programs can perform core dumps (value 1, for debugging)\"\n            Display --indent 2 --text \"- Checking setuid core dumps configuration\" --result \"${STATUS_DEBUG}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Determine if all binaries need to be able to core dump\"\n            AddHP 0 1\n        else\n            # 0 - (default) - traditional behaviour. Any process which has changed privilege levels or is execute only will not be dumped\n            # https://www.kernel.org/doc/Documentation/sysctl/fs.txt\n            LogText \"Result: found default option (0), no execute only program or program with changed privilege levels can dump\"\n            Display --indent 4 --text \"- Checking setuid core dumps configuration\" --result \"${STATUS_DISABLED}\" --color GREEN\n            AddHP 1 1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : KRNL-5830\n    # Description : Check if system needs a reboot (Linux only)\n    Register --test-no KRNL-5830 --os Linux --weight L --network NO --category security --description \"Checking if system is running on the latest installed kernel\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        REBOOT_NEEDED=2\n        for FILE in \"${ROOTDIR}var/run/reboot-required.pkgs\" \"${ROOTDIR}var/run/needs_restarting\"\n        do\n            LogText \"Test: Checking presence ${FILE}\"\n            if [ -f ${FILE} ]; then\n                LogText \"Result: file ${FILE} exists\"\n                FIND=$(${WCBINARY} -l < ${FILE})\n                if [ \"${FIND}\" = \"0\" ]; then\n                    LogText \"Result: No reboot needed (file empty)\"\n                    REBOOT_NEEDED=0\n                    break\n                else\n                    PKGSCOUNT=$(${WCBINARY} -l < ${FILE})\n                    LogText \"Result: reboot is needed, related to ${PKGSCOUNT} packages\"\n                    for I in ${FIND}; do\n                        LogText \"Package: ${I}\"\n                    done\n                    REBOOT_NEEDED=1\n                    break\n                fi\n            else\n                LogText \"Result: file ${FILE} not found\"\n            fi\n        done\n\n        # Check if /boot exists\n        if [ -d \"${ROOTDIR}boot\" ]; then\n            LogText \"Result: /boot exists, performing more tests from here\"\n            FIND=$(${LSBINARY} ${ROOTDIR}boot/* 2> /dev/null)\n            if [ -n \"${FIND}\" ]; then\n                if [ -f ${ROOTDIR}boot/vmlinuz -a ! -L ${ROOTDIR}boot/vmlinuz ]; then\n                    LogText \"Result: found /boot/vmlinuz (not symlinked)\"\n                    NEXTLINE=0\n                    FINDVERSION=\"\"\n                    for I in $(file ${ROOTDIR}boot/vmlinuz-linux); do\n                        if [ ${NEXTLINE} -eq 1 ]; then\n                            FINDVERSION=\"${I}\"\n                            break\n                        else\n                            # Searching for the Linux kernel after the keyword 'version'\n                            if [ \"${I}\" = \"version\" ]; then NEXTLINE=1; fi\n                        fi\n                    done\n                    if [ -n \"${FINDVERSION}\" ]; then\n                        CURRENT_KERNEL=$(uname -r)\n                        if [ ! \"${CURRENT_KERNEL}\" = \"${FINDVERSION}\" ]; then\n                            LogText \"Result: reboot needed, as current kernel is different than the one loaded\"\n                            REBOOT_NEEDED=1\n                        fi\n                    else\n                        ReportException \"${TEST_NO}:1\" \"Can't determine kernel version on disk, need debug data\"\n                    fi\n                elif [ -f ${ROOTDIR}boot/vmlinuz-linux ] || [ -f ${ROOTDIR}boot/vmlinuz-linux-lts ] || [ -f \"$(${LSBINARY} -t ${ROOTDIR}boot/vm[l0-9]* 2> /dev/null | ${HEADBINARY} -1)\" ]; then\n                    if [ -f ${ROOTDIR}boot/vmlinuz ]; then\n                          LogText \"Result: found ${ROOTDIR}boot/vmlinuz\"\n                          FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz\n                    elif [ -f ${ROOTDIR}boot/vmlinuz-linux ]; then\n                        LogText \"Result: found ${ROOTDIR}boot/vmlinuz-linux\"\n                        FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz-linux\n                    elif [ -f ${ROOTDIR}boot/vmlinuz-linux-lts ]; then\n                        LogText \"Result: found ${ROOTDIR}boot/vmlinuz-linux-lts\"\n                        FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz-linux-lts\n                    elif [ -f ${ROOTDIR}boot/vmlinuz-lts ]; then\n                        LogText \"Result: found ${ROOTDIR}boot/vmlinuz-lts\"\n                        FOUND_VMLINUZ=${ROOTDIR}boot/vmlinuz-lts\n                    else\n                        # Match on items like /boot/vm5.3.7 or /boot/vmlinuz-5.3.7-1-default. Sort based on versions (-v) and then find the last item\n                        # Note: ignore a rescue kernel (e.g. CentOS)\n                        FOUND_VMLINUZ=$(${LSBINARY} -v ${ROOTDIR}boot/vm[l0-9]* 2> /dev/null | ${GREPBINARY} -v '\\-rescue-' | ${TAILBINARY} -1)\n                        LogText \"Result: found ${FOUND_VMLINUZ}\"\n                    fi\n\n                    VERSION_ON_DISK=\"\"\n                    if [ -L \"${FOUND_VMLINUZ}\" ]; then\n                        LogText \"Result: found a symlink, retrieving destination\"\n                        FOUND_VMLINUZ=$(readlink \"${FOUND_VMLINUZ}\")\n                        LogText \"Result: destination file is ${FOUND_VMLINUZ}\"\n                        VERSION_ON_DISK=$(echo ${FOUND_VMLINUZ} | ${SEDBINARY} 's#^/boot/##' | ${SEDBINARY} 's/^vmlinuz-//')\n                        LogText \"Result: version derived from file name is '${VERSION_ON_DISK}'\"\n                    elif [ -f \"${FOUND_VMLINUZ}\" ]; then\n                        VERSION_ON_DISK=$(echo ${FOUND_VMLINUZ} | ${SEDBINARY} 's#^/boot/##' | ${SEDBINARY} 's/^vmlinuz-//' | ${SEDBINARY} '$s/-\\?\\(linux\\)\\?-\\?\\(lts\\)\\?//')\n                        LogText \"Result: version derived from file name is '${VERSION_ON_DISK}'\"\n\n                    fi\n\n                    # Data check: perform reset if we found a version but looks incomplete\n                    # Example: Arch Linux will return only 'linux' as its version after it discovered /boot/vmlinuz-linux\n                    case ${VERSION_ON_DISK} in\n                        \"linux\" | \"linux-lts\")\n                            LogText \"Result: reset of version (${VERSION_ON_DISK}) as it looks incomplete\"\n                            VERSION_ON_DISK=\"\"\n                        ;;\n                    esac\n\n                    # If we did not find the version yet, see if we can extract it from the magic data that 'file' returns\n                    if [ -z \"${VERSION_ON_DISK}\" ]; then\n                        LogText \"Test: checking kernel version on disk\"\n                        NEXTLINE=0\n                        VERSION_ON_DISK=\"\"\n                        for I in $(file ${FOUND_VMLINUZ}); do\n                            if [ ${NEXTLINE} -eq 1 ]; then\n                                VERSION_ON_DISK=\"${I}\"\n                                break\n                            else\n                                # Searching for the Linux kernel after the keyword 'version'\n                                if [ \"${I}\" = \"version\" ]; then NEXTLINE=1; fi\n                            fi\n                        done\n                    fi\n\n                    # Last check if we finally got a version or not\n                    if [ -z \"${VERSION_ON_DISK}\" ]; then\n                        LogText \"Result: could not find the version on disk\"\n                        ReportException \"${TEST_NO}:4\" \"Could not find the kernel version\"\n                    else\n                        LogText \"Result: found version ${VERSION_ON_DISK}\"\n                        ACTIVE_KERNEL=$(uname -r)\n                        LogText \"Result: active kernel version ${ACTIVE_KERNEL}\"\n                        if [ \"${VERSION_ON_DISK}\" = \"${ACTIVE_KERNEL}\" ]; then\n                            REBOOT_NEEDED=0\n                            LogText \"Result: no reboot needed, active kernel is the same version as the one on disk\"\n                        else\n                            REBOOT_NEEDED=1\n                            LogText \"Result: reboot needed, as there is a difference between active kernel and the one on disk\"\n                        fi\n                    fi\n                else\n                    if [ -L ${ROOTDIR}boot/vmlinuz ]; then\n                        LogText \"Result: found symlink of ${ROOTDIR}boot/vmlinuz, skipping file\"\n                    else\n                        LogText \"Result: ${ROOTDIR}boot/vmlinuz not on disk, trying to find ${ROOTDIR}boot/vmlinuz*\"\n                    fi\n                    # Extra current kernel version and replace dashes to allow numeric ${SORTBINARY} later on\n                    MYKERNEL=$(${UNAMEBINARY} -r | ${SEDBINARY} 's/\\.[a-z].*.//g' | ${SEDBINARY} 's/-[a-z].*.//g' | ${SEDBINARY} 's/-/./g')\n                    LogText \"Result: using ${MYKERNEL} as my kernel version (stripped)\"\n                    FIND=$(ls ${ROOTDIR}boot/vmlinuz* 2> /dev/null)\n                    if [ -n \"${FIND}\" ]; then\n                        for ITEM in ${FIND}; do\n                            LogText \"Result: found ${ITEM}\"\n                        done\n                        # Display kernels, extract version numbers and ${SORTBINARY} them numeric per column (up to 6 numbers)\n                        # Ignore rescue images. Remove generic. and huge. for Slackware machines\n                        # TODO: see if this can be simplified using ls -v sorting\n                        LogText \"Action: checking relevant kernels\"\n                        KERNELS=$(${LSBINARY} /boot/vmlinuz* | ${GREPBINARY} -v rescue | ${SEDBINARY} 's/vmlinuz-//' | ${SEDBINARY} 's/generic.//' | ${SEDBINARY} 's/huge.//' | ${SEDBINARY} 's/\\.[a-z].*.//g' | ${SEDBINARY} 's/-[a-z].*.//g' | ${SEDBINARY} 's./boot/..' | ${SEDBINARY} 's/-/./g' | ${SORTBINARY} -n -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -t \\.)\n                        KERNELS_ONE_LINE=$(${ECHOCMD} ${KERNELS} | ${TRBINARY} '\\n' ' ')\n                        LogText \"Output: ${KERNELS_ONE_LINE}\"\n                    elif [ ! \"$(ls ${ROOTDIR}boot/kernel* 2> /dev/null)\" = \"\" ]; then\n                        LogText \"Output: Found a kernel file in ${ROOTDIR}boot\"\n                        # Display kernels, extract version numbers and ${SORTBINARY} them numeric per column (up to 6 numbers)\n                        # Examples:\n                        # /boot/kernel-genkernel-x86_64-3.14.14-gentoo\n                        KERNELS=$(${LSBINARY} ${ROOTDIR}boot/kernel* | ${AWKBINARY} -F- '{ if ($2==\"genkernel\") { print $4 }}' | ${GREPBINARY} \"^[0-9]\" | ${SORTBINARY} -n -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 -k6,6 -t \\.)\n                        if [ -n \"${KERNELS}\" ]; then LogText \"Output: ${KERNELS}\"; fi\n                    else\n                        ReportException \"${TEST_NO}:2\" \"Can not find any vmlinuz or kernel files in /boot, which is unexpected\"\n                    fi\n                    if [ -n \"${KERNELS}\" ]; then\n                        FOUND_KERNEL=0\n                        for I in ${KERNELS}; do\n                            # Check if we already found a kernel and it is not equal to what we run (e.g. double versions may exist)\n                            if [ ${FOUND_KERNEL} -eq 1 -a ! \"${MYKERNEL}\" = \"${I}\" ]; then\n                                LogText \"Result: found a kernel (${I}) later than active kernel (${MYKERNEL})\"\n                                REBOOT_NEEDED=1\n                            fi\n                            if [ \"${MYKERNEL}\" = \"${I}\" ]; then\n                                FOUND_KERNEL=1\n                                LogText \"Result: found ${I} (= active kernel)\"\n                            else\n                                LogText \"Result: found ${I}\"\n                            fi\n                        done\n                        # Check if we at least found the kernel on disk\n                        if [ ${FOUND_KERNEL} -eq 0 ]; then\n                            ReportException \"${TEST_NO}:3\" \"Could not find our running kernel on disk, which is unexpected\"\n                        else\n                            # If we are not sure yet reboot it needed, but we found running kernel as last one on disk, we run latest kernel\n                            if [ ${REBOOT_NEEDED} -eq 2 ]; then\n                                LogText \"Result: found the running kernel on disk being the last entry, so it looks up-to-date\"\n                                REBOOT_NEEDED=0\n                            fi\n                        fi\n                    fi\n                fi\n            # No files in /boot\n            else\n                LogText \"Result: Skipping this test, as there are no files in /boot\"\n            fi\n        else\n            LogText \"Result: /boot does not exist or not privileged to read files\"\n        fi\n\n        # Attempt to check for Raspbian if reboot is needed\n        # This check searches for apt package \"raspberrypi-kernel-[package-date]\", trys to extract the date of packaging from the filename\n        # and compares that date with the currently running kernel's build date (uname -v).\n        # Of course there can be a time difference between kernel build and kernel packaging, therefore a time difference of\n        # 3 days is accepted and it is assumed with only 3 days apart, this must be the same kernel version.\n        if [ ${REBOOT_NEEDED} -eq 2 ] && [ -d \"${APT_ARCHIVE_DIRECTORY}\" ]; then\n            LogText \"Result: found folder ${APT_ARCHIVE_DIRECTORY}; assuming this is a debian based distribution\"\n            LogText \"Check: try to find raspberrypi-kernel file in ${APT_ARCHIVE_DIRECTORY} and extract package date from file name\"\n\n            FOUND_KERNEL_DATE=$(${FINDBINARY} ${APT_ARCHIVE_DIRECTORY} -name \"raspberrypi-kernel*\" -printf \"%T@ %Tc %p\\n\" 2> /dev/null \\\n            | ${SORTBINARY} -nr | ${HEADBINARY} -1 | ${GREPBINARY} -o \"raspberrypi-kernel.*deb\" | ${GREPBINARY} -E -o \"\\.[0-9]+\" | ${SEDBINARY} 's/\\.//g')\n\n            if [ -n \"${FOUND_KERNEL_DATE}\" ]; then\n                FOUND_KERNEL_IN_SECONDS=$(date -d \"${FOUND_KERNEL_DATE}\" \"+%s\" 2> /dev/null)\n            else\n                LogText \"Result: Skipping this test, as there was no package date to extract\"\n            fi\n\n            if [ -n \"${FOUND_KERNEL_IN_SECONDS}\" ] && [ ${FOUND_KERNEL_IN_SECONDS} -gt 1 ]; then\n                LogText \"Result: Got package date: ${FOUND_KERNEL_DATE} (= ${FOUND_KERNEL_IN_SECONDS} seconds)\"\n                UNAME_OUTPUT=\"$(${UNAMEBINARY} -v 2> /dev/null)\"\n            else\n                LogText \"Result: Skipping this test, as extracting the seconds of package date failed\"\n            fi\n\n            if [ -n \"${UNAME_OUTPUT}\" ]; then\n                LogText \"Result: Got an output from 'uname -v'\"\n                LogText \"Check: Trying to extract kernel build date from 'uname -v' output\"\n                next=\"\"\n                for part in ${UNAME_OUTPUT}; do\n                    if [ -z \"$next\" ]; then\n                        if [ \"${part}\" = \"Mon\" ] || [ \"${part}\" = \"Tue\" ] || [ \"${part}\" = \"Wed\" ] || [ \"${part}\" = \"Thu\" ] || [ \"${part}\" = \"Fri\" ] || [ \"${part}\" = \"Sat\" ] || [ \"${part}\" = \"Sun\" ]; then\n                            next=\"month\"\n                        fi\n                    elif [ \"$next\" = \"month\" ]; then\n                        if [ $(${ECHOCMD} \"${part}\" | ${GREPBINARY} -E -c \"[A-Z][a-z]\") -ge 1 ]; then\n                            UNAME_DATE_MONTH=\"${part}\"\n                            next=\"day\"\n                        fi\n                    elif [ \"${next}\" = \"day\" ]; then\n                        if [ $(${ECHOCMD} ${part} | ${GREPBINARY} -E -c \"[0-9][0-9]\") -ge 1 ]; then\n                            UNAME_DATE_DAY=\"${part}\"\n                            next=\"time\"\n                        fi\n                    elif [ \"${next}\" = \"time\" ]; then\n                        if [ $(${ECHOCMD} ${part} | ${GREPBINARY} -E -c \":[0-9][0-9]:\") -ge 1 ]; then\n                            next=\"year\"\n                        fi\n                    elif [ \"${next}\" = \"year\" ]; then\n                        if [ $(${ECHOCMD} ${part} | ${GREPBINARY} -E -c \"[0-9][0-9]\") -ge 1 ]; then\n                            UNAME_DATE_YEAR=\"${part}\"\n                            break\n                        fi\n                    fi\n                done\n                if [ -n \"${UNAME_DATE_MONTH}\" ] && [ -n \"${UNAME_DATE_DAY}\" ] && [ -n \"${UNAME_DATE_YEAR}\" ]; then\n                    LogText \"Result: Extracted kernel build date is: ${UNAME_DATE_DAY} ${UNAME_DATE_MONTH} ${UNAME_DATE_YEAR}\"\n                    UNAME_DATE_IN_SECONDS=$(date -d \"${UNAME_DATE_DAY} ${UNAME_DATE_MONTH} ${UNAME_DATE_YEAR}\" \"+%s\" 2> /dev/null)\n                    LogText \"Check: Comparing kernel build date in seconds (${UNAME_DATE_IN_SECONDS}s) with package date in seconds (${FOUND_KERNEL_IN_SECONDS}s)\"\n                    if [ -n \"${UNAME_DATE_IN_SECONDS}\" ] && [ ${FOUND_KERNEL_IN_SECONDS} -ge ${UNAME_DATE_IN_SECONDS} ]; then\n                        LogText \"Result: package creation date is older than running kernel. Hence, this check should be valid.\"\n                        LogText \"Check if package create date and kernel build date are not more than 3 days apart.\"\n\n                        SECONDS_APART=$(( ${FOUND_KERNEL_IN_SECONDS} - ${UNAME_DATE_IN_SECONDS} ))\n                        if [ ${SECONDS_APART} -ge 60 ]; then\n                            MINUTES_APART=$(( ${SECONDS_APART} / 60 ))\n                            if [ ${MINUTES_APART} -ge 60 ]; then\n                                DAYS_APART=$(( ${MINUTES_APART} / 60 ))\n                                if [ ${DAYS_APART} -ge 24 ]; then DAYS_APART=$(( ${DAYS_APART} / 24 )); else DAYS_APART=0; fi\n                            else\n                                DAYS_APART=0\n                            fi\n                        else\n                            DAYS_APART=0\n                        fi\n                        # assuming kernels are packaged definitely within 3 days. ACCEPTED_TIME_DIFF needs a value in seconds\n                        ACCEPTED_TIME_DIFF=$((3 * 24 * 60 * 60))\n                        if [ ${FOUND_KERNEL_IN_SECONDS} -le $((${UNAME_DATE_IN_SECONDS} + ${ACCEPTED_TIME_DIFF})) ]; then\n                            LogText \"Result: package create date and kernel build date are only ${DAYS_APART} day(s) apart.\"\n                            LogText \"Result: Assuming no reboot needed.\"\n                            REBOOT_NEEDED=0\n                        else\n                            LogText \"Result: package create date and kernel build date are ${DAYS_APART} day(s) apart.\"\n                            LogText \"Result: Assuming reboot is needed.\"\n                            REBOOT_NEEDED=1\n                        fi\n                    else\n                        LogText \"Result: Package's create date is older than running kernel, which is unexpected. Might not be a valid test. Skipping...\"\n                    fi\n                else\n                    LogText \"Result: Could not extract Day, Month and Year from 'uname -v' output\"\n                fi\n            else\n                LogText \"Result: Did not get output from 'uname -v'. Skipping test.\"\n            fi\n\n        else\n            LogText \"Result: /var/cache/apt/archives/ does not exist\"\n        fi\n\n        # Display discovered status\n        if [ ${REBOOT_NEEDED} -eq 0 ]; then\n            Display --indent 2 --text \"- Check if reboot is needed\" --result \"${STATUS_NO}\" --color GREEN\n            AddHP 5 5\n        elif [ ${REBOOT_NEEDED} -eq 1 ]; then\n            Display --indent 2 --text \"- Check if reboot is needed\" --result \"${STATUS_YES}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Reboot of system is most likely needed\" \"\" \"text:reboot\"\n            AddHP 0 5\n        else\n            Display --indent 2 --text \"- Check if reboot is needed\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_kernel_hardening",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Kernel\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_KERNEL_HARDENING}\"\n#\n#################################################################################\n#\n    # Test        : KRNL-6000\n    # Description : Check sysctl parameters\n    # Sysctl      : net.ipv4.icmp_ignore_bogus_error_responses (=1)\n    if [ ! \"${SYSCTL_READKEY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no KRNL-6000 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check sysctl key pairs in scan profile\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        DATA_TO_SCAN=\"\"\n        N=0\n        Display --indent 2 --text \"- Comparing sysctl key pairs with scan profile\"\n\n        # First scan optional profiles only (ignore default and custom)\n        for PROFILE in ${PROFILES}; do\n            FILE=$(echo ${PROFILE} | ${AWKBINARY} -F/ '{print $NF}')\n            if [ ! \"${FILE}\" = \"default.prf\" -a ! \"${FILE}\" = \"custom.prf\" ]; then\n                FIND=$(${GREPBINARY} \"^config-data=sysctl;\" ${PROFILE} | ${SEDBINARY} 's/ /-space-/g')\n                DATA_TO_SCAN=\"${DATA_TO_SCAN} ${FIND}\"\n            fi\n        done\n\n        # Scan custom profile\n        if [ -n \"${CUSTOM_PROFILE}\" ]; then\n            FIND=$(${GREPBINARY} \"^config-data=sysctl;\" ${CUSTOM_PROFILE} | ${SEDBINARY} 's/ /-space-/g')\n            for LINE in ${FIND}; do\n                SYSCTLKEY=$(echo ${LINE} | ${AWKBINARY} -F\\; '{ print $2 }')\n                HAS_KEY=$(echo ${DATA_TO_SCAN} | ${GREPBINARY} \";${SYSCTLKEY};\")\n                if [ $? -gt 0 ]; then DATA_TO_SCAN=\"${DATA_TO_SCAN} ${LINE}\"; fi\n            done\n        fi\n\n        # Last, use data from default profile\n        if [ -n \"${DEFAULT_PROFILE}\" ]; then\n            FIND=$(${GREPBINARY} \"^config-data=sysctl;\" ${DEFAULT_PROFILE} | ${SEDBINARY} 's/ /-space-/g')\n            for LINE in ${FIND}; do\n                SYSCTLKEY=$(echo ${LINE} | ${AWKBINARY} -F\\; '{ print $2 }')\n                HAS_KEY=$(echo ${DATA_TO_SCAN} | ${GREPBINARY} \";${SYSCTLKEY};\")\n                if [ $? -gt 0 ]; then DATA_TO_SCAN=\"${DATA_TO_SCAN} ${LINE}\"; fi\n            done\n        fi\n\n        # Sort the results\n        DATA_TO_SCAN=$(echo ${DATA_TO_SCAN} | ${TRBINARY} ' ' '\\n' | sort)\n\n        for line in ${DATA_TO_SCAN}; do\n            tFINDkey=$(echo ${line} | ${AWKBINARY} -F\\; '{ print $2 }')\n            if ! SkipAtomicTest \"${TEST_NO}:${tFINDkey}\"; then\n                tFINDexpvalue=$(echo ${line} | ${AWKBINARY} -F\\; '{ print $3 }' | ${TRBINARY} '|' ' ')\n                tFINDhp=$(echo ${line} | ${AWKBINARY} -F\\; '{ print $4 }' | ${GREPBINARY} \"[0-9]\")\n                tFINDdesc=$(echo ${line} | ${AWKBINARY} -F\\; '{ print $5 }' | ${SEDBINARY} 's/-space-/ /g')\n                tFINDcurvalue=$(${SYSCTL_READKEY} ${tFINDkey} 2> /dev/null)\n                if [ -n \"${tFINDcurvalue}\" ]; then\n                    positive_match=0\n                    for value in ${tFINDexpvalue}; do\n                        if [ \"${value}\" = \"${tFINDcurvalue}\" ]; then\n                            positive_match=1\n                        fi\n                    done\n                    if [ ${positive_match} -eq 1 ]; then\n                        LogText \"Result: sysctl key ${tFINDkey} contains equal expected and current value (${tFINDexpvalue})\"\n                        Display --indent 4 --text \"- ${tFINDkey} (exp: ${tFINDexpvalue})\" --result \"${STATUS_OK}\" --color GREEN\n                        AddHP ${tFINDhp} ${tFINDhp}\n                    else\n                        LogText \"Result: sysctl key ${tFINDkey} has a different value than expected in scan profile. Expected=${tFINDexpvalue}, Real=${tFINDcurvalue}\"\n                        Display --indent 4 --text \"- ${tFINDkey} (exp: ${tFINDexpvalue})\" --result \"${STATUS_DIFFERENT}\" --color RED\n                        AddHP 0 ${tFINDhp}\n                        FOUND=1\n                        N=$((N + 1))\n                        ReportDetails --test \"${TEST_NO}\" --service \"sysctl\" --field \"${tFINDkey}\" --value \"${tFINDcurvalue}\" --preferredvalue \"${tFINDexpvalue}\" --description \"${tFINDdesc}\"\n                    fi\n                else\n                    LogText \"Result: key ${tFINDkey} does not exist on this machine\"\n                fi\n            else\n                LogText \"Skipped test for ${tFINDkey} via profile\"\n            fi\n        done\n\n        # Add suggestion if one or more sysctls have a different value than scan profile\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: found ${N} keys that can use tuning, according scan profile\"\n            ReportSuggestion \"${TEST_NO}\" \"One or more sysctl values differ from the scan profile and could be tweaked\" \"\" \"Change sysctl value or disable test (skip-test=${TEST_NO}:<sysctl-key>)\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_ldap",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# LDAP Services\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_LDAP_SERVICES}\"\n#\n#################################################################################\n#\n    SLAPD_CONF_LOCS=\"${ROOTDIR}etc/ldap ${ROOTDIR}etc/openldap ${ROOTDIR}usr/local/etc/openldap\"\n    SLAPD_CONF_LOCATION=\"\"\n    SLAPD_RUNNING=0\n#\n#################################################################################\n#\n    # Test        : LDAP-2219\n    # Description : Check running OpenLDAP instance\n    Register --test-no LDAP-2219 --weight L --network NO --category security --description \"Check running OpenLDAP instance\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning \"slapd\"; then\n            Display --indent 2 --text \"- Checking OpenLDAP instance\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found running slapd process\"\n            SLAPDFOUND=1\n            SLAPD_RUNNING=1\n        else    \n            Display --indent 2 --text \"- Checking OpenLDAP instance\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: No running slapd process found.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LDAP-2224\n    # Description : Search slapd.conf\n    if [ ${SLAPD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LDAP-2224 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check presence slapd.conf\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching slapd.conf\"\n        for I in ${SLAPD_CONF_LOCS}; do\n            if [ -f ${I}/slapd.conf ]; then\n                LogText \"Result: found ${I}/slapd.conf\"\n                SLAPD_CONF_LOCATION=\"${I}/slapd.conf\"\n            else\n                LogText \"Result: ${I} does not contain slapd.conf\"\n            fi\n        done\n        # Check if we found a valid location\n        if [ -n \"${SLAPD_CONF_LOCATION}\" ]; then\n            Display --indent 4 --text \"- Checking slapd.conf\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            Display --indent 4 --text \"- Checking slapd.conf\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LDAP-2228\n    # Description : Check OpenLDAP slapd.conf file permissions\n#\n#################################################################################\n#\n    # Test        : LDAP-2232\n    # Description : Check OpenLDAP ownership on files/directories\n#\n#################################################################################\n#\n    # Test        : LDAP-2236\n    # Description : Check OpenLDAP database permissions\n#\n#################################################################################\n#\n    # Test        : LDAP-2240\n    # Description : Check OpenLDAP plaintext RootDN password\n#\n#################################################################################\n#\n    # Test        : LDAP-2244\n    # Description : Check for LDAP configured client (and inform about LDAPS)\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_logging",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Logging and related files\n#\n#################################################################################\n#\n    LOG_FILES_LOCS=\"${ROOTDIR}var/log ${ROOTDIR}var/adm\"\n    LOGROTATE_CONFIG_FOUND=0\n    LOGROTATE_TOOL=\"\"\n    METALOG_RUNNING=0\n    RFC3195D_RUNNING=0\n    RSYSLOG_RUNNING=0\n    WAZUH_AGENT_RUNNING=0\n    SOLARIS_LOGHOST=\"\"\n    SOLARIS_LOGHOST_FOUND=0\n    SOLARIS_LOGHOST_LOCALHOST=0\n    SYSLOG_DAEMON_PRESENT=0\n    SYSLOG_DAEMON_RUNNING=0\n    SYSLOG_NG_RUNNING=0\n    SYSTEMD_JOURNAL_RUNNING=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_LOGGING_AND_FILES}\"\n\n    # Test        : LOGG-2130\n    # Description : Check for a running syslog daemon\n    Register --test-no LOGG-2130 --weight L --network NO --category security --description \"Check for running syslog daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for a logging daemon\"\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} -E \"syslogd|syslog-ng|metalog|systemd-journal\" | ${GREPBINARY} -v \"grep\")\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking for a running log daemon\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Could not find a syslog daemon like syslog, syslog-ng, rsyslog, metalog, systemd-journal\"\n            ReportSuggestion \"${TEST_NO}\" \"Check if any syslog daemon is running and correctly configured.\"\n            AddHP 0 3\n        else\n            Display --indent 2 --text \"- Checking for a running log daemon\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: Found a logging daemon\"\n            SYSLOG_DAEMON_PRESENT=1\n            SYSLOG_DAEMON_RUNNING=1\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2132\n    # Description : Check for a running syslog-ng daemon\n    Register --test-no LOGG-2132 --weight L --network NO --category security --description \"Check for running syslog-ng daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for syslog-ng daemon in process list\"\n        if IsRunning \"syslog-ng\"; then\n            LogText \"Result: Found syslog-ng in process list\"\n            Display --indent 4 --text \"- Checking Syslog-NG status\" --result \"${STATUS_FOUND}\" --color GREEN\n            SYSLOG_DAEMON_PRESENT=1\n            SYSLOG_NG_RUNNING=1\n            Report \"syslog_daemon_present=1\"\n            Report \"syslog_daemon[]=syslog-ng\"\n        else\n            LogText \"Result: Syslog-ng NOT found in process list\"\n            Display --indent 4 --text \"- Checking Syslog-NG status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2134\n    # Description : Check for Syslog-NG configuration file consistency\n    if [ ! \"${SYSLOGNGBINARY}\" = \"\" -a ${SYSLOG_NG_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2134 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking Syslog-NG configuration file consistency\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSLOGNGBINARY} -s; echo $?)\n        if [ \"${FIND}\" = \"0\" ]; then\n            LogText \"Result: Syslog-NG configuration file seems to be consistent\"\n            Display --indent 6 --text \"- Checking Syslog-NG consistency\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            LogText \"Result: Syslog-NG configuration file seems NOT to be consistent\"\n            Display --indent 6 --text \"- Checking Syslog-NG consistency\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check the Syslog-NG configuration file and/or run a manual consistency check with: syslog-ng -s\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2136\n    # Description : Check for a running systemd-journal daemon\n    Register --test-no LOGG-2136 --weight L --network NO --category security --description \"Check for running systemd journal daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for systemd journal daemon in process list\"\n        if IsRunning \"systemd-journal\"; then\n            Display --indent 4 --text \"- Checking systemd journal status\" --result \"${STATUS_FOUND}\" --color GREEN\n            SYSTEMD_JOURNAL_RUNNING=1\n            Report \"syslog_daemon_present=1\"\n            Report \"syslog_daemon[]=systemd-journal\"\n        else\n            Display --indent 4 --text \"- Checking systemd journal status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2210\n    # Description : Check for a running metalog daemon\n    Register --test-no LOGG-2210 --weight L --network NO --category security --description \"Check for running metalog daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for metalog daemon in process list\"\n        if IsRunning \"metalog\"; then\n            LogText \"Result: Found metalog in process list\"\n            Display --indent 4 --text \"- Checking Metalog status\" --result \"${STATUS_FOUND}\" --color GREEN\n            SYSLOG_DAEMON_PRESENT=1\n            METALOG_RUNNING=1\n            Report \"syslog_daemon_present=1\"\n            Report \"syslog_daemon[]=metalog\"\n        else\n            LogText \"Result: metalog NOT found in process list\"\n            Display --indent 4 --text \"- Checking Metalog status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2230\n    # Description : Check for a running rsyslog daemon\n    Register --test-no LOGG-2230 --weight L --network NO --category security --description \"Check for running RSyslog daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for RSyslog daemon in process list\"\n        if IsRunning \"rsyslogd\"; then\n            LogText \"Result: Found rsyslogd in process list\"\n            Display --indent 4 --text \"- Checking RSyslog status\" --result \"${STATUS_FOUND}\" --color GREEN\n            SYSLOG_DAEMON_PRESENT=1\n            RSYSLOG_RUNNING=1\n            Report \"syslog_daemon_present=1\"\n            Report \"syslog_daemon[]=rsyslog\"\n        else\n            LogText \"Result: rsyslogd NOT found in process list\"\n            Display --indent 4 --text \"- Checking RSyslog status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2240\n    # Description : Check for a running RFC 3195 compliant daemon (syslog via TCP)\n    Register --test-no LOGG-2240 --weight L --network NO --category security --description \"Check for running RFC 3195 compliant daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for RFC 3195 daemon (alias syslog reliable) in process list\"\n        if IsRunning \"rfc3195d\"; then\n            LogText \"Result: Found rfc3195d in process list\"\n            Display --indent 4 --text \"- Checking RFC 3195 daemon status\" --result \"${STATUS_FOUND}\" --color GREEN\n            SYSLOG_DAEMON_PRESENT=1\n            RFC3195D_RUNNING=1\n        else\n            LogText \"Result: rfc3195d NOT found in process list\"\n            Display --indent 4 --text \"- Checking RFC 3195 daemon status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2138\n    # Description : Check for kernel log daemon (klogd) presence on Linux systems\n    # Notes       : * When using metalog, rsyslog or systemd (systemd-journal), this process is not needed.\n    #               * In combination with syslog-ng, klogd is still an addition to it, since it\n    #                 captures kernel related events and send them to syslog-ng.\n    #               * This test should be below all other logging daemons\n    Register --test-no LOGG-2138 --os Linux --weight L --network NO --category security --description \"Checking kernel logger daemon on Linux\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching kernel logger daemon (klogd)\"\n        if [ ${RSYSLOG_RUNNING} -eq 0 ] && [ ${SYSTEMD_JOURNAL_RUNNING} -eq 0 ] && [ ${METALOG_RUNNING} -eq 0 ]; then\n            # Search for klogd, but ignore other lines related to klogd (like dd with input/output file)\n            #FIND=$(${PSBINARY} ax | ${GREPBINARY} \"klogd\" | ${GREPBINARY} -v \"dd\" | ${GREPBINARY} -v \"grep\")\n            if IsRunning \"klogd\"; then\n                LogText \"Result: klogd running\"\n                Display --indent 4 --text \"- Checking klogd\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                LogText \"Result: No klogd found\"\n                Display --indent 4 --text \"- Checking klogd\" --result \"${STATUS_NOT_FOUND}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"klogd is not running, which could lead to missing kernel messages in log files\"\n            fi\n        else\n            LogText \"Result: test skipped, because other facility is being used to log kernel messages\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2142\n    # Description : Check for minilogd presence on Linux systems\n    Register --test-no LOGG-2142 --os Linux --weight L --network NO --category security --description \"Checking minilog daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Result: Checking for unkilled minilogd instances\"\n        # Search for minilogd. It shouldn't be running normally, if another syslog daemon is started\n        if IsRunning \"minilogd\"; then\n            Display --indent 4 --text \"- Checking minilogd instances\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: minilogd found in process list\"\n            # minilogd daemon seems to be running\n            ReportWarning \"${TEST_NO}\" \"minilogd is running, which should normally not be running\"\n        else\n            Display --indent 4 --text \"- Checking minilogd instances\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: No minilogd is running\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2144\n    # Description : Check for wazuh-agent presence on Linux systems\n    Register --test-no LOGG-2144 --os Linux --weight L --network NO --category security --description \"Checking wazuh-agent\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Result: Searching for wazuh-agent instances in the process list\"\n        if IsRunning \"wazuh-agentd\"; then\n            LogText \"Result: Found wazuh-agent in process list\"\n            Display --indent 4 --text \"- Checking wazuh-agent status\" --result \"${STATUS_FOUND}\" --color GREEN\n            WAZUH_AGENT_RUNNING=1\n        else\n            LogText \"Result: wazuh-agent NOT found in process list\"\n            Display --indent 4 --text \"- Checking wazuh-agent daemon status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2146\n    # Description : Check for logrotate (/etc/logrotate.conf and logrotate.d)\n    Register --test-no LOGG-2146 --weight L --os Linux --network NO --category security --description \"Checking logrotate.conf and logrotate.d\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for ${ROOTDIR}etc/logrotate.conf\"\n        if [ -f ${ROOTDIR}etc/logrotate.conf ]; then\n            LOGROTATE_CONFIG_FOUND=1\n            LOGROTATE_TOOL=\"logrotate\"\n            LogText \"Result: ${ROOTDIR}etc/logrotate.conf found (file)\"\n        else\n            LogText \"Result: ${ROOTDIR}etc/logrotate.conf NOT found\"\n        fi\n\n        LogText \"Test: Checking for ${ROOTDIR}etc/logrotate.d (directory)\"\n        if [ -d ${ROOTDIR}etc/logrotate.d ]; then\n            LOGROTATE_CONFIG_FOUND=1\n            LOGROTATE_TOOL=\"logrotate\"\n            LogText \"Result: ${ROOTDIR}etc/logrotate.d found\"\n        else\n            LogText \"Result: ${ROOTDIR}etc/logrotate.conf found\"\n        fi\n\n        if [ ${LOGROTATE_CONFIG_FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking logrotate presence\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: logrotate configuration found\"\n        else\n            Display --indent 2 --text \"- Checking logrotate presence\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: No logrotate configuration found\"\n            ReportSuggestion \"${TEST_NO}\" \"Check if log files are properly rotated\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2148\n    # Description : Checking log files rotated with logrotate\n    if [ -n \"${LOGROTATEBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2148 --weight L --preqs-met ${PREQS_MET} --network NO --category security --description \"Checking logrotated files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking which files are rotated with logrotate and if they exist\"\n        FIND=$(${LOGROTATEBINARY} -d -v ${ROOTDIR}etc/logrotate.conf 2>&1 | ${GREPBINARY} -E \"considering log|skipping\" | ${GREPBINARY} -v '*' | ${SORTBINARY} -u | ${AWKBINARY} '{ if ($2!=\"log\") { print \"File:\"$2\":does_not_exist\" } else { print \"File:\"$3\":exists\" } }')\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: nothing found\"\n        else\n            LogText \"Result: found one or more files which are rotated via logrotate\"\n            for I in ${FIND}; do\n                LogText \"Output: ${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2150\n    # Description : Checking log directories rotated with logrotate\n    if HasData \"${LOGROTATEBINARY}\"; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2150 --weight L --preqs-met ${PREQS_MET} --network NO --category security --description \"Checking directories in logrotate configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking which directories can be found in logrotate configuration\"\n        FIND=$(${LOGROTATEBINARY} -d -v ${ROOTDIR}etc/logrotate.conf 2>&1 | ${GREPBINARY} -E \"considering log|skipping\" | ${GREPBINARY} -v '*' | ${SORTBINARY} -u | ${AWKBINARY} '{ if ($2==\"log\") { print $3 } }' | ${SEDBINARY} 's@/[^/]*$@@g' | ${SORTBINARY} -u)\n        if IsEmpty \"${FIND}\"; then\n            LogText \"Result: nothing found\"\n        else\n            LogText \"Result: found one or more directories (via logrotate configuration)\"\n            for DIR in ${FIND}; do\n                if [ -d ${DIR} ]; then\n                    LogText \"Directory found: ${DIR}\"\n                    Report \"log_directory[]=${DIR}\"\n                else\n                    LogText \"Result: Directory could not be found: ${DIR}\"\n                fi\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2152\n    # Description : Check for Solaris 'loghost' entry in /etc/inet/hosts, or\n    #               successful resolving via DNS or any other name service.\n    Register --test-no LOGG-2152 --weight L --os Solaris --network NO --category security --description \"Checking loghost\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Try local hosts file\n        LogText \"Result: Checking for loghost in /etc/inet/hosts\"\n        FIND=$(${GREPBINARY} loghost /etc/inet/hosts | ${GREPBINARY} -v \"^#\")\n        if [ -n \"${FIND}\" ]; then\n            SOLARIS_LOGHOST=\"${FIND}\"\n            SOLARIS_LOGHOST_FOUND=1\n            LogText \"Result: Found loghost entry in /etc/inet/hosts\"\n        else\n            LogText \"Result: No loghost entry found in /etc/inet/hosts\"\n\n            # Try name resolving if no entry is present in local host file\n            LogText \"Result: Checking for loghost via name resolving\"\n            FIND=$(getent hosts loghost | ${GREPBINARY} loghost)\n            if [ -n \"${FIND}\" ]; then\n                SOLARIS_LOGHOST=\"${FIND}\"\n                SOLARIS_LOGHOST_FOUND=1\n                LogText \"Result: name resolving was successful\"\n                LogText \"Output: ${FIND}\"\n            else\n                LogText \"Result: name resolving didn't find results\"\n            fi\n        fi\n\n        if [ ${SOLARIS_LOGHOST_FOUND} -eq 1 ]; then\n            LogText \"Result: loghost entry found and most likely used to send syslog messages\"\n            Display --indent 2 --text \"- Checking loghost entry\" --result \"${STATUS_OK}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Checking loghost entry\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: No loghost entry found\"\n            ReportWarning \"${TEST_NO}\" \"No loghost entry found\"\n            ReportSuggestion \"${TEST_NO}\" \"Add a loghost entry to /etc/inet/hosts or other name services\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2153\n    # Description : Check Solaris 'loghost' entry is not localhost, meaning\n    #               remote logging is not configured.\n    if [ ${SOLARIS_LOGHOST_FOUND} -eq 1 ] && [ -n \"${SOLARIS_LOGHOST}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2153 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking loghost is localhost\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(echo \"${SOLARIS_LOGHOST}\" | ${AWKBINARY} '{ print $1 }' | ${GREPBINARY} -E \"::1|127.0.0.1|127.1\")\n        if [ -n \"${FIND}\" ]; then\n            SOLARIS_LOGHOST_LOCALHOST=1\n            LogText \"Result: loghost entry is localhost (default)\"\n            Display --indent 4 --text \"- Checking loghost entry is localhost\" --result \"${STATUS_YES}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Set loghost entry to a remote location to enable remote logging.\"\n        else\n            Display --indent 4 --text \"- Checking loghost entry is localhost\" --result \"${STATUS_NO}\" --color GREEN\n        fi\n    fi\n\n#\n#################################################################################\n#\n    # Test        : LOGG-2154\n    # Description : Check to see if remote logging is enabled\n    # Notes       : prevent lines showing up with commands in it (like |mail)\n    if [ ${SYSLOG_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2154 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking syslog configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        if [ ${RSYSLOG_RUNNING} -eq 1 ]; then\n            DATA=\"\"\n            TARGET=\"${ROOTDIR}etc/rsyslog.conf\"\n            if [ -f ${TARGET} ]; then\n                LogText \"Test: analyzing file ${TARGET} for remote target\"\n                DATA=$(${GREPBINARY} -E \"@@?([a-zA-Z0-9\\-])+(\\.)?(([a-zA-Z0-9-])+)?(\\.)?(([a-zA-Z0-9-])+)?(\\.)?(([a-zA-Z0-9-])+)?(\\.)?(([a-zA-Z0-9-])+)?\" ${TARGET} | ${GREPBINARY} -v \"#\" | ${TRBINARY} -cd \"[:print:]\\n\" | ${SEDBINARY} 's/[[:blank:]]\\{1,\\}/:space:/g')\n                if [ -z \"${DATA}\" ]; then\n                    LogText \"Result: no remote target found\"\n                else\n                    LogText \"Result: found remote target\"\n                    REMOTE_LOGGING_ENABLED=1\n                    for D in ${DATA}; do\n                        if SafeInput \"${D}\"; then\n                            D=$(echo ${D} | ${SEDBINARY} 's/:space:/ /g')\n                            LogText \"Data: ${D}\"\n                        fi\n                    done\n                fi\n            fi\n            TARGET=\"${ROOTDIR}etc/rsyslog.d\"\n            if [ -d ${TARGET} ]; then\n                FILES=$(${FINDBINARY} -L ${TARGET} -type f -print0 | ${TRBINARY} -cd '[:print:]\\0' | ${SEDBINARY} 's/[[:blank:]]/:space:/g' | ${TRBINARY} '\\0' ' ')\n                for F in ${FILES}; do\n                    F=$(echo ${F} | ${SEDBINARY} 's/:space:/ /g')\n                    LogText \"Test: analyzing file ${F} for remote target\"\n                    DATA=$(${GREPBINARY} -E \"@@?([a-zA-Z0-9\\-])+(\\.)?(([a-zA-Z0-9-])+)?(\\.)?(([a-zA-Z0-9-])+)?(\\.)?(([a-zA-Z0-9-])+)?(\\.)?(([a-zA-Z0-9-])+)?\" ${F} | ${GREPBINARY} -v \"#\" | ${TRBINARY} -cd \"[:print:]\\n\" | ${SEDBINARY} 's/[[:blank:]]\\{1,\\}/:space:/g')\n                    if [ -n \"${DATA}\" ]; then\n                        LogText \"Result: found remote target\"\n                        REMOTE_LOGGING_ENABLED=1\n                        for D in ${DATA}; do\n                            if SafeInput \"${D}\"; then\n                                D=$(echo ${D} | ${SEDBINARY} 's/:space:/ /g')\n                                LogText \"Data: ${D}\"\n                            fi\n                        done\n                    else\n                        # Check new style configuration (omrelp/omfwd). This can be all on one line or even split over multiple lines.\n                        DATA=$(${GREPBINARY} -E \"target=\\\"([a-zA-Z0-9\\-])\" ${F})\n                        if [ -n \"${DATA}\" ]; then\n                            LogText \"Result: most likely remote log host is used, as keyword 'target' is used\"\n                            REMOTE_LOGGING_ENABLED=1\n                        else\n                            LogText \"Result: no remote target found\"\n                        fi\n                    fi\n                done\n            fi\n        fi\n\n        # Test generic syslog files (syslog-ng and older syslog daemons)\n        if [ ${SYSLOG_NG_RUNNING} -eq 1 ]; then\n            SYSLOGD_CONF=\"${ROOTDIR}etc/syslog-ng/syslog-ng.conf\"\n        else\n            SYSLOGD_CONF=\"${ROOTDIR}etc/syslog.conf\"\n        fi\n\n        if [ -f ${SYSLOGD_CONF} ]; then\n            LogText \"Test: check if logs are also logged to a remote logging host\"\n            FIND=$(${GREPBINARY} -E \"@[a-zA-Z0-9]|destination\\s.+(udp|tcp).+\\sport\" ${SYSLOGD_CONF} | ${GREPBINARY} -v \"^#\" | ${GREPBINARY} -v \"[a-zA-Z0-9]@\")\n            if [ -n \"${FIND}\" ]; then\n                FIND2=$(echo \"${FIND}\" | ${GREPBINARY} -v \"@loghost\")\n                if [ ${SOLARIS_LOGHOST_LOCALHOST} -eq 1 ] && [ -z \"${FIND2}\" ]; then\n                    LogText \"Result: remote logging enabled to loghost, but loghost is localhost\"\n                else\n                    LogText \"Result: remote logging enabled\"\n                    REMOTE_LOGGING_ENABLED=1\n                fi\n            else\n                # Search for configured destinations with an IP address or hostname, then determine which ones are used as a log destination\n                DESTINATIONS=$(${GREPBINARY} \"^destination\" ${SYSLOGD_CONF} | ${GREPBINARY} -E \"(udp|tcp)\" | ${GREPBINARY} \"port\" | ${AWKBINARY} '{print $2}')\n                for DESTINATION in ${DESTINATIONS}; do\n                    FIND2=$(${GREPBINARY} \"log\" ${SYSLOGD_CONF} | ${GREPBINARY} \"source\" | ${GREPBINARY} -E \"destination\\(${DESTINATION}\\)\")\n                    if [ -n \"${FIND2}\" ]; then\n                        LogText \"Result: found destination ${DESTINATION} configured for remote logging\"\n                        REMOTE_LOGGING_ENABLED=1\n                    fi\n                done\n            fi\n        fi\n\n        # Test wazuh-agent configuration for syslog configuration\n        if [ ${WAZUH_AGENT_RUNNING} ]; then\n            WAZUH_AGENT_CONF=\"/var/ossec/etc/ossec.conf\"\n        fi\n\n        if [ -f ${WAZUH_AGENT_CONF} ]; then\n            LogText \"Test: Checking Wazuh agent configuration for remote syslog forwarding\"\n            FIND=$(${EGREPBINARY} '<location>/var/log/syslog</location>' ${WAZUH_AGENT_CONF})\n            if [ \"${FIND}\" ]; then\n                DESTINATION=$(${EGREPBINARY} -o '<address>([A-Za-z0-9\\.\\-\\_]*)</address>' ${WAZUH_AGENT_CONF} | sed 's/<address>//' | sed 's/<\\/address>//')\n                LogText \"Result: found destination ${DESTINATION} configured for remote logging with wazuh\"\n                REMOTE_LOGGING_ENABLED=1\n            fi\n        fi\n\n        # Show result\n        if [ ${REMOTE_LOGGING_ENABLED} -eq 0 ]; then\n            Report \"remote_syslog_configured=0\"\n            LogText \"Result: no remote logging found\"\n            ReportSuggestion \"${TEST_NO}\" \"Enable logging to an external logging host for archiving purposes and additional protection\"\n            AddHP 1 3\n            Display --indent 2 --text \"- Checking remote logging\" --result \"${STATUS_NOT_ENABLED}\" --color YELLOW\n        else\n            Report \"remote_syslog_configured=1\"\n            AddHP 5 5\n            Display --indent 2 --text \"- Checking remote logging\" --result \"${STATUS_ENABLED}\" --color GREEN\n        fi\n\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2160\n    # Description : Check for /etc/newsyslog.conf (FreeBSD/OpenBSD)\n    if [ -f ${ROOTDIR}etc/newsyslog.conf ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2160 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking /etc/newsyslog.conf\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Result: ${ROOTDIR}etc/newsyslog.conf found\"\n        Display --indent 2 --text \"- Checking ${ROOTDIR}etc/newsyslog.conf\" --result \"${STATUS_FOUND}\" --color GREEN\n        LOGROTATE_CONFIG_FOUND=1\n        LOGROTATE_TOOL=\"newsyslog\"\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2162\n    # Description : Check for directories in /etc/newsyslog.conf\n    if [ -f /etc/newsyslog.conf ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2162 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking directories in /etc/newsyslog.conf\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: parsing directories from /etc/newsyslog.conf file\"\n        FIND=$(${AWKBINARY} '/^\\// { print $1 }' /etc/newsyslog.conf | ${SEDBINARY} 's/\\/*[a-zA-Z_.-]*$//g' | ${SORTBINARY} -u)\n        for I in ${FIND}; do\n            if [ -d ${I} ]; then\n                LogText \"Result: Directory ${I} found and exists\"\n                Report \"log_directory[]=${I}\"\n            else\n                LogText \"Result: Item ${I} is not a directory\"\n            fi\n        done\n        Display --indent 4 --text \"- Checking log directories (newsyslog.conf)\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2164\n    # Description : Check for files in /etc/newsyslog.conf\n    if [ -f ${ROOTDIR}etc/newsyslog.conf ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2164 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking files specified /etc/newsyslog.conf\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: parsing files from ${ROOTDIR}etc/newsyslog.conf file\"\n        FIND=$(${AWKBINARY} '/^\\// { print $1 }' ${ROOTDIR}etc/newsyslog.conf | ${SORTBINARY} -u)\n        for I in ${FIND}; do\n            if [ -f ${I} ]; then\n                LogText \"Result: File ${I} found and exists\"\n            else\n                LogText \"Result: Item ${I} is not a file\"\n            fi\n        done\n        Display --indent 4 --text \"- Checking log files (newsyslog.conf)\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2170\n    # Description : Search available log paths\n    Register --test-no LOGG-2170 --weight L --network NO --category security --description \"Checking log paths\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching log paths\"\n        for I in ${LOG_FILES_LOCS}; do\n            if [ -d ${I} ]; then\n                LogText \"Result: directory ${I} exists\"\n                Report \"log_directory[]=${I}\"\n            else\n                LogText \"Result: directory ${I} can't be found\"\n            fi\n        done\n        Display --indent 2 --text \"- Checking log directories (static list)\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2180\n    # Description : Search open log file\n    Register --test-no LOGG-2180 --weight L --network NO --category security --description \"Checking open log files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking open log files with lsof\"\n        if [ -n \"${LSOFBINARY}\" ]; then\n            FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -n 2>&1 | ${GREPBINARY} \"log$\" | ${GREPBINARY} -E -v \"WARNING|Output information\" | ${AWKBINARY} '{ if ($5==\"REG\") { print $9 } }' | ${SORTBINARY} -u | ${GREPBINARY} -v \"^$\")\n            for I in ${FIND}; do\n                LogText \"Found logfile: ${I}\"\n            done\n            Display --indent 2 --text \"- Checking open log files\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            LogText \"Result: lsof not installed, skipping test\"\n            Display --indent 2 --text \"- Checking open log files\" --result \"${STATUS_SKIPPED}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2190\n    # Description : Checking deleted files\n    if [ -n \"${LSOFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2190 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking for deleted files in use\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        EARLY_MYSQL=\"\"\n        LogText \"Test: checking deleted files that are still in use\"\n\n        LSOF_GREP=\"WARNING|Output information\"\n\n        # MySQL versions prior to 5.6 leave lots of deleted in-use files in /tmp, ignoring those\n        LSOF_GREP=\"${LSOF_GREP}|mysqld\"\n\n        # grsecurity causes Fail2Ban to hold onto deleted in-use files in /var/tmp\n        if [ ${GRSEC_FOUND} -eq 1 ]; then LSOF_GREP=\"${LSOF_GREP}|fail2ban\"; fi\n        if [ ${OS_REDHAT_OR_CLONE} -eq 1 ]; then\n            # If lynis is run from /etc/cron.daily some deleted in-use files are kept in /tmp\n            LSOF_GREP=\"${LSOF_GREP}|anacron|awk|run-parts\"\n        fi\n\n        FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -n +L 1 2>&1 | ${GREPBINARY} -E -vw \"${LSOF_GREP}\" | ${GREPBINARY} -E -v '/dev/zero|/\\[aio\\]' | ${AWKBINARY} '{ if ($5==\"REG\") { printf \"%s(%s)\\n\", $10, $1 } }' | ${GREPBINARY} -v \"^$\" | ${SORTBINARY} -u)\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found one or more files which are deleted, but still in use\"\n            for I in ${FIND}; do\n                LogText \"Found deleted file: ${I}\"\n                Report \"deleted_file[]=${I}\"\n            done\n            Display --indent 2 --text \"- Checking deleted files in use\" --result \"${STATUS_FILES_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Check what deleted files are still in use and why.\"\n        else\n            LogText \"Result: no deleted files found\"\n            Display --indent 2 --text \"- Checking deleted files in use\" --result \"${STATUS_DONE}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : LOGG-2192\n    # Description : Check for open log files which are empty. This may indicate a problem with log rotation, or unused services\n    if [ -n \"${LSOFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no LOGG-2192 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking for open log files that are empty\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -n -w | ${AWKBINARY} '{if ($5==\"REG\" && $7==\"0\" && $9 ~ /log$/) {print $1\",\"$9}}' | ${SORTBINARY} | uniq)\n        if [ -n \"${FIND}\" ]; then\n            for I in ${FIND}; do\n                LogText \"Found an opened logfile that is empty: ${I}\"\n                Report \"open_empty_log_file[]=${I}\"\n            done\n        else\n            LogText \"Result: all opened log files are bigger than zero bytes in size\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nReport \"log_rotation_config_found=${LOGROTATE_CONFIG_FOUND}\"\nReport \"log_rotation_tool=${LOGROTATE_TOOL}\"\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_mac_frameworks",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    APPARMORFOUND=0                     # Set default for test MACF-6208\n    MAC_FRAMEWORK_ACTIVE=0              # Default no MAC framework active\n    RBAC_FRAMEWORK_ACTIVE=0             # Default no RBAC framework active\n    SELINUXFOUND=0\n    TOMOYOFOUND=0\n\n    InsertSection \"${SECTION_SECURITY_FRAMEWORKS}\"\n#\n#################################################################################\n#\n    # Test        : MACF-6204\n    # Description : Check if AppArmor is installed\n    Register --test-no MACF-6204 --weight L --network NO --category security --description \"Check AppArmor presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -z \"${AASTATUSBINARY}\" ]; then\n            APPARMORFOUND=0\n            LogText \"Result: aa-status binary not found, AppArmor not installed\"\n            Display --indent 2 --text \"- Checking presence AppArmor\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        else\n            APPARMORFOUND=1\n            LogText \"Result: aa-status binary found, AppArmor is installed\"\n            Display --indent 2 --text \"- Checking presence AppArmor\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MACF-6208\n    # Description : Check AppArmor active status\n    if [ ${APPARMORFOUND} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MACF-6208 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check if AppArmor is enabled\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${AASTATUSBINARY}\" ]; then\n            CAN_READ_FILE=0\n            FILE=\"/sys/kernel/security/apparmor/profiles\"\n            if [ -f ${FILE} ]; then\n                FIND=$(${CAT_BINARY} ${FILE} 2> /dev/null)\n                if [ $? -eq 0 ]; then CAN_READ_FILE=1; fi\n            else\n                LogText \"File ${FILE} does not exist\"\n            fi\n            if [ ${CAN_READ_FILE} -eq 1 ]; then\n                LogText \"Result: file ${FILE} is available and readable\"\n                # Checking AppArmor status\n                # 0 if apparmor is enabled and policy is loaded.\n                # 1 if apparmor is not enabled/loaded.\n                # 2 if apparmor is enabled but no policy is loaded.\n                # 3 if control files are not available\n                # 4 if apparmor status can't be read\n                FIND=$(${AASTATUSBINARY} 2>&1 > /dev/null)\n                if [ $? -eq 0 ]; then\n                    MAC_FRAMEWORK_ACTIVE=1\n                    LogText \"Result: AppArmor is enabled and a policy is loaded\"\n                    Display --indent 4 --text \"- Checking AppArmor status\" --result \"${STATUS_ENABLED}\" --color GREEN\n                    Report \"apparmor_enabled=1\"\n                    Report \"apparmor_policy_loaded=1\"\n                    AddHP 3 3\n                    # ignore kernel threads (Parent PID = 2 [kthreadd])\n                    NUNCONFINED=$(${PSBINARY} -N --ppid 2 -o label | ${GREPBINARY} '^unconfined' | ${WCBINARY} -l)\n                    Display --indent 8 --text \"Found ${NUNCONFINED} unconfined processes\"\n                    for PROCESS in $(${PSBINARY} -N --ppid 2 -o label:1,pid,comm | ${GREPBINARY} '^unconfined' | ${TRBINARY} ' ' ':'); do\n                        LogText \"Result: Unconfined process: ${PROCESS}\"\n                    done\n                elif [ $? -eq 4 ]; then\n                    LogText \"Result: Can not determine status, most likely due to lacking permissions\"\n                    Display --indent 4 --text \"- Checking AppArmor status\" --result \"${STATUS_UNKNOWN}\" --color RED\n                elif [ $? -eq 3 ]; then\n                    LogText \"Result: Can not check control files\"\n                    Display --indent 4 --text \"- Checking AppArmor status\" --result \"${STATUS_UNKNOWN}\" --color RED\n                elif [ $? -eq 2 ]; then\n                    LogText \"Result: AppArmor is enabled, but no policy is loaded\"\n                    ReportSuggestion \"${TEST_NO}\" \"Load AppArmor policies\"\n                    Display --indent 4 --text \"- Checking AppArmor status\" --result \"NON-ACTIVE\" --color GREEN\n                    Report \"apparmor_enabled=1\"\n                    Report \"apparmor_policy_loaded=0\"\n                    AddHP 0 3\n                elif [ $? -eq 1 ]; then\n                    LogText \"Result: AppArmor is disabled\"\n                    Display --indent 4 --text \"- Checking AppArmor status\" --result \"${STATUS_DISABLED}\" --color YELLOW\n                    Report \"apparmor_enabled=0\"\n                    AddHP 0 3\n                else\n                    Display --indent 4 --text \"- Checking AppArmor status\" --result \"${STATUS_UNKNOWN}\" --color RED\n                    ReportException \"${TEST_NO}:1\" \"Invalid or unknown AppArmor status detected\"\n                fi\n            else\n                LogText \"Result: could not find or read ${FILE}\"\n                Display --indent 4 --text \"- Checking AppArmor status\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Check output of aa-status\" \"${FILE}\" \"text:Run aa-status\"\n            fi\n        else\n            LogText \"Result: no aa-status binary available\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MACF-6232\n    # Description : Check SELINUX for installation\n    Register --test-no MACF-6232 --weight L --network NO --category security --description \"Check SELINUX presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking if we have sestatus binary\"\n        if [ -n \"${SESTATUSBINARY}\" ]; then\n            LogText \"Result: found sestatus binary (${SESTATUSBINARY})\"\n            Display --indent 2 --text \"- Checking presence SELinux\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: sestatus binary NOT found\"\n            Display --indent 2 --text \"- Checking presence SELinux\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MACF-6234\n    # Description : Check SELINUX status\n    if HasData \"${SESTATUSBINARY}\"; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MACF-6234 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check SELINUX status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Status: Enabled/Disabled\n        FIND=$(${SESTATUSBINARY} | ${GREPBINARY} \"^SELinux status\" | ${AWKBINARY} '{ print $3 }')\n        if [ \"${FIND}\" = \"enabled\" ]; then\n            MAC_FRAMEWORK_ACTIVE=1\n            LogText \"Result: SELinux framework is enabled\"\n            Report \"selinux_status=1\"\n            SELINUXFOUND=1\n            Display --indent 4 --text \"- Checking SELinux status\" --result \"${STATUS_ENABLED}\" --color GREEN\n            FIND=$(${SESTATUSBINARY} | ${GREPBINARY} \"^Current mode\" | ${AWKBINARY} '{ print $3 }')\n            Report \"selinux_mode=${FIND}\"\n            FIND2=$(${SESTATUSBINARY} | ${GREPBINARY} \"^Mode from config file\" | ${AWKBINARY} '{ print $5 }')\n            LogText \"Result: current SELinux mode is ${FIND}\"\n            LogText \"Result: mode configured in config file is ${FIND2}\"\n            if [ \"${FIND}\" = \"${FIND2}\" ]; then\n                LogText \"Result: Current SELinux mode is the same as in config file.\"\n                Display --indent 6 --text \"- Checking current mode and config file\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: Current SELinux mode (${FIND}) is NOT the same as in config file (${FIND2}).\"\n                ReportWarning \"${TEST_NO}\" \"Current SELinux mode is different from config file (current: ${FIND}, config file: ${FIND2})\"\n                Display --indent 6 --text \"- Checking current mode and config file\" --result \"${STATUS_WARNING}\" --color RED\n            fi\n            Display --indent 8 --text \"Current SELinux mode: ${FIND}\"\n            if [ -n \"${SEMANAGEBINARY}\" ]; then\n                PERMISSIVE=$(${SEMANAGEBINARY} permissive --list --noheading | ${TRBINARY} '\\n' ' ')\n                NPERMISSIVE=$(${SEMANAGEBINARY} permissive --list --noheading | ${WCBINARY} -l)\n                Display --indent 8 --text \"Found ${NPERMISSIVE} permissive SELinux object types\"\n                LogText \"Permissive SELinux object types: ${PERMISSIVE}\"\n            else\n                LogText \"Result: semanage binary NOT found, can't analyse permissive domains\"\n            fi\n            UNCONFINED=$(${PSBINARY} -eo label,pid,command | ${GREPBINARY} '[u]nconfined_t' | ${TRBINARY} '\\n' ' ')\n            INITRC=$(${PSBINARY} -eo label,pid,command | ${GREPBINARY} '[i]nitrc_t' | ${TRBINARY} '\\n' ' ')\n            NUNCONFINED=$(${PSBINARY} -eo label | ${GREPBINARY} '[u]nconfined_t' | ${WCBINARY} -l)\n            NINITRC=$(${PSBINARY} -eo label | ${GREPBINARY} '[i]nitrc_t' | ${WCBINARY} -l)\n            Display --indent 8 --text \"Found ${NUNCONFINED} unconfined and ${NINITRC} initrc_t processes\"\n            LogText \"Unconfined processes: ${UNCONFINED}\"\n            LogText \"Processes with initrc_t type: ${INITRC}\"\n        else\n            LogText \"Result: SELinux framework is disabled\"\n            Display --indent 4 --text \"- Checking SELinux status\" --result \"${STATUS_DISABLED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MACF-6240\n    # Description : Check if the tomoyo-init binary is available on the system\n    Register --test-no MACF-6240 --weight L --network NO --category security --description \"Check TOMOYO Linux presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking if we have tomoyo-init binary\"\n        if [ -z \"${TOMOYOINITBINARY}\" ]; then\n            TOMOYOFOUND=0\n            LogText \"Result: tomoyo-init binary not found\"\n            Display --indent 2 --text \"- Checking presence TOMOYO Linux\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        else\n            TOMOYOFOUND=1\n            LogText \"Result: tomoyo-init binary found\"\n            Display --indent 2 --text \"- Checking presence TOMOYO Linux\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MACF-6242\n    # Description : Check TOMOYO Linux status\n    if [ ${TOMOYOFOUND} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MACF-6242 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check TOMOYO Linux status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FILE=\"/sys/kernel/security/tomoyo/stat\"\n        if [ -f ${FILE} ]; then\n            MAC_FRAMEWORK_ACTIVE=1\n            LogText \"Result: TOMOYO Linux is enabled\"\n            Display --indent 4 --text \"- Checking TOMOYO Linux status\" --result \"${STATUS_ENABLED}\" --color GREEN\n            Report \"tomoyo_enabled=1\"\n            if [ ! -z ${TOMOYOPSTREEBINARY} ]; then\n                NUNCONFINED=$(${TOMOYOPSTREEBINARY} | ${GREPBINARY} -v '^  3 ' | ${WCBINARY} -l)\n                Display --indent 8 --text \"Found ${NUNCONFINED} unconfined (not profile 3) processes\"\n                for PROCESS in $(${TOMOYOPSTREEBINARY} | ${GREPBINARY} -v '^  3 ' | ${SEDBINARY} -e 's/+-//g' -e 's/^ *//g' -e 's/ \\+/:/g' | ${SORTBINARY}); do\n                    LogText \"Result: Unconfined process: ${PROCESS}\"\n                done\n            fi\n            AddHP 3 3\n        else\n            LogText \"Result: TOMOYO Linux is disabled\"\n            Display --indent 4 --text \"- Checking TOMOYO Linux status\" --result \"${STATUS_DISABLED}\" --color YELLOW\n            Report \"tomoyo_enabled=0\"\n            AddHP 0 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : RBAC-6272\n    # Description : Check if grsecurity is installed\n    # Notes       : We already checked grsecurity in osdetection\n    Register --test-no RBAC-6272 --weight L --network NO --category security --description \"Check grsecurity presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check Linux kernel configuration\n        if [ -n \"${LINUXCONFIGFILE}\" -a -f \"${LINUXCONFIGFILE}\" ]; then\n            FIND=$(${GREPBINARY} ^CONFIG_GRKERNSEC=y ${LINUXCONFIGFILE})\n            if [ ! \"${FIND}\" = \"\" ]; then\n                LogText \"Result: grsecurity available (in kernel config)\"\n                GRSEC_FOUND=1\n            else\n                LogText \"Result: no grsecurity found in kernel config\"\n            fi\n        fi\n        if [ ${GRSEC_FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking presence grsecurity\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- Checking presence grsecurity\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n        if HasData \"${GRADMBINARY}\"; then\n            FIND=$(${GRADMBINARY} --status 2>/dev/null)\n            if [ \"${FIND}\" = \"The RBAC system is currently enabled.\" ]; then\n                MAC_FRAMEWORK_ACTIVE=1\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MACF-6290\n    # Description : Check if at least one MAC framework is implemented\n    Register --test-no MACF-6290 --weight L --network NO --category security --description \"Check for implemented MAC framework\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${MAC_FRAMEWORK_ACTIVE} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking for implemented MAC framework\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 3 3\n            LogText \"Result: found implemented MAC framework\"\n        else\n            Display --indent 2 --text \"- Checking for implemented MAC framework\" --result \"${STATUS_NONE}\" --color YELLOW\n            AddHP 2 3\n            LogText \"Result: found no implemented MAC framework\"\n        fi\n     fi\n#\n#################################################################################\n#\n\nReport \"framework_grsecurity=${GRSEC_FOUND}\"\nReport \"framework_selinux=${SELINUXFOUND}\"\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_mail_messaging",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# E-mail and messaging\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_EMAIL_AND_MESSAGING}\"\n#\n#################################################################################\n#\n    DOVECOT_RUNNING=0\n    EXIM_RUNNING=0\n    EXIM_TYPE=\"\"\n    IMAP_DAEMON=\"\"\n    OPENSMTPD_RUNNING=0\n    POP3_DAEMON=\"\"\n    POSTFIX_RUNNING=0\n    QMAIL_RUNNING=0\n    SENDMAIL_RUNNING=0\n    SMTP_DAEMON=\"\"\n#\n#################################################################################\n#\n    # Test        : MAIL-8802\n    # Description : Check Exim process status\n    Register --test-no MAIL-8802 --weight L --network NO --category security --description \"Check Exim status\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: check Exim status\"\n        if IsRunning \"exim4\" || IsRunning \"exim\"; then\n            LogText \"Result: found running Exim process\"\n            Display --indent 2 --text \"- Exim status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            EXIM_RUNNING=1\n            SMTP_DAEMON=\"exim\"\n            Report \"smtp_daemon[]=exim\"\n        else\n            LogText \"Result: no running Exim processes found\"\n            if IsVerbose; then Display --indent 2 --text \"- Exim status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8804\n    # Description : Exim configuration options\n    if [ ${EXIM_RUNNING} -eq 1 -a ! \"${EXIMBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MAIL-8804 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Exim configuration options\"\n    if [ ${SKIPTEST} -eq 0 -a ${EXIM_RUNNING} -eq 1 ]; then\n        LogText \"Test: Exim configuration options\"\n\n        EXIM_ROUTERS=$(${EXIMBINARY} -bP router_list)\n\n        unset FIND FIND2 FIND3 FIND4\n\n        # Local Only\n        FIND=$(echo \"${EXIM_ROUTERS}\" | ${GREPBINARY} -E '^nonlocal')\n        # Internet Host\n        FIND2=$(echo \"${EXIM_ROUTERS}\" | ${GREPBINARY} -E '^dnslookup_relay_to_domains')\n        # Smarthost or Satellite\n        FIND3=$(echo \"${EXIM_ROUTERS}\" | ${GREPBINARY} -E '^smarthost')\n\n        if [ -n \"${FIND}\" ]; then\n            EXIM_TYPE=\"LOCAL ONLY\"\n        elif [ -n \"${FIND2}\" ]; then\n            EXIM_TYPE=\"INTERNET HOST\"\n        elif [ -n \"${FIND3}\" ]; then\n            FIND4=$(echo \"${EXIM_ROUTERS}\" | ${GREPBINARY} -E '^hub_user_smarthost')\n            if [ -n \"${FIND4}\" ]; then\n                EXIM_TYPE=\"SATELLITE\"\n            else\n                EXIM_TYPE=\"SMARTHOST\"\n            fi\n        fi\n\n        if [ -n \"${EXIM_TYPE}\" ]; then\n            LogText \"Result: Exim Type - ${EXIM_TYPE}\"\n            Display --indent 4 --text \"- Type\" --result \"${EXIM_TYPE}\" --color GREEN\n        else\n            LogText \"Result: Exim Type - Not Configured\"\n            Display --indent 4 --text \"- Type\" --result \"${STATUS_NOT_CONFIGURED}\" --color WHITE\n        fi\n\n        if [ \"${EXIM_TYPE}\" = \"INTERNET HOST\" -o \"${EXIM_TYPE}\" = \"SMARTHOST\" ]; then\n            LogText \"Test: Exim Public Interfaces\"\n            EXIM_IP=$(${EXIMBINARY} -bP local_interfaces | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/\\s*<\\s*\\;\\?//' -e 's/\\s*::0\\s*\\;\\?//' -e 's/\\s*127.0.0.1\\s*\\;\\?//' -e 's/^\\s*//' -e 's/\\s*$//')\n            if [ -n \"${EXIM_IP}\" ]; then\n                LogText \"Result: ${EXIM_IP}\"\n                Display --indent 4 --text \"- Public Interface(s)\" --result \"${EXIM_IP}\" --color GREEN\n            else\n                LogText \"Result: None\"\n                Display --indent 4 --text \"- Public Interface(s)\" --result \"NONE\" --color WHITE\n            fi\n\n            LogText \"Test: Exim TLS State\"\n            EXIM_TLS=$(${EXIMBINARY} -bP tls_advertise_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n            if [ -n \"${EXIM_TLS}\" ]; then\n                LogText \"Result: Enabled\"\n                Display --indent 4 --text \"- TLS\" --result \"${STATUS_ENABLED}\" --color GREEN\n            else\n                LogText \"Result: Not enabled\"\n                Display --indent 4 --text \"- TLS\" --result \"${STATUS_DISABLED}\" --color WHITE\n            fi\n        fi\n\n        if [ -n \"${EXIM_TYPE}\" -a \"${EXIM_TYPE}\" != \"LOCAL ONLY\" ]; then\n            LogText \"Test: Exim Certificate and Private Key\"\n\n            case \"${EXIM_TYPE}\" in\n                \"INTERNET HOST\" | \"SMARTHOST\" )\n                    EXIM_CERTIFICATE=$(${EXIMBINARY} -bP tls_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    EXIM_PRIVATEKEY=$(${EXIMBINARY} -bP tls_privatekey | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    ;;\n                \"SATELLITE\" )\n                    EXIM_CERTIFICATE=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    EXIM_PRIVATEKEY=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_privatekey | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    ;;\n            esac\n\n            if [ -n \"${EXIM_CERTIFICATE}\" ]; then\n                LogText \"Result: ${EXIM_CERTIFICATE}\"\n                if [ -f \"${EXIM_CERTIFICATE}\" ]; then\n                    Display --indent 4 --text \"- Certificate\" --result \"${STATUS_FOUND}\" --color GREEN\n                    LogText \"Result: Certificate found\"\n                else\n                    Display --indent 4 --text \"- Certificate\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    LogText \"Result: Certificate not found\"\n                fi\n            else\n                LogText \"Result: Certificate not set\"\n                Display --indent 4 --text \"- Certificate\" --result \"${STATUS_NOT_CONFIGURED}\" --color WHITE\n            fi\n\n            if [ -n \"${EXIM_PRIVATEKEY}\" ]; then\n                LogText \"Result: ${EXIM_PRIVATEKEY}\"\n                if [ -f \"${EXIM_PRIVATEKEY}\" ]; then\n                    LogText \"Result: Private Key found\"\n                    Display --indent 4 --text \"- Private Key\" --result \"${STATUS_FOUND}\" --color GREEN\n                else\n                    Display --indent 4 --text \"- Private Key\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    LogText \"Result: Private Key not found\"\n                fi\n            else\n                LogText \"Result: Private Key not set\"\n                Display --indent 4 --text \"- Private Key\" --result \"${STATUS_NOT_CONFIGURED}\" --color WHITE\n            fi\n\n            LogText \"Test: Exim Verify Certificates\"\n\n            case \"${EXIM_TYPE}\" in\n                \"INTERNET HOST\" | \"SMARTHOST\" )\n                    EXIM_CERTIFICATES=$(${EXIMBINARY} -bP tls_verify_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    ;;\n                \"SATELLITE\" )\n                    EXIM_CERTIFICATES=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_verify_certificate | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    ;;\n            esac\n\n            case \"${EXIM_CERTIFICATES}\" in\n                \"\")\n                    # This condition results in a RED warning because it should never be hit\n                    LogText \"Result: Verify Certificates not set\"\n                    Display --indent 4 --text \"- Verify Certificates not set\" --result \"${STATUS_WARNING}\" --color RED\n                    ;;\n                \"system\")\n                    # This is the default setting and should be the most common\n                    LogText \"Result: Verify Certificates set to system default\"\n                    Display --indent 4 --text \"- Verify Certificates\" --result \"DEFAULT\" --color WHITE\n                    ;;\n                *)\n                    # This condition should only be hit when it has been set to a custom value\n                    LogText \"Result: Verify Certificates set to \\\"${EXIM_CERTIFICATES}\\\"\"\n                    Display --indent 4 --text \"- Verify Certificates\" --result \"CUSTOM\" --color GREEN\n                    ;;\n            esac\n\n\n            case \"${EXIM_TYPE}\" in\n                \"INTERNET HOST\" | \"SMARTHOST\" )\n                    EXIM_VERIFY_HOSTS=$(${EXIMBINARY} -bP tls_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    EXIM_TRY_VERIFY_HOSTS=$(${EXIMBINARY} -bP tls_try_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    ;;\n                \"SATELLITE\" )\n                    EXIM_VERIFY_HOSTS=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    EXIM_TRY_VERIFY_HOSTS=$(${EXIMBINARY} -bP transport remote_smtp_smarthost | ${GREPBINARY} tls_try_verify_hosts | ${CUTBINARY} -d '=' -f2 | ${SEDBINARY} -e 's/^\\s*//' -e 's/\\s*$//')\n                    ;;\n            esac\n\n            LogText \"Test: Exim Try Verify Hosts\"\n            if [ -n \"${EXIM_TRY_VERIFY_HOSTS}\" ]; then\n                LogText \"Result: Try Verify Hosts enabled\"\n                case \"${EXIM_TYPE}\" in\n                    \"INTERNET HOST\" )\n                        Display --indent 4 --text \"- Try Verify Hosts\" --result \"${STATUS_ENABLED}\" --color GREEN\n                        ;;\n                    \"SATELLITE\" | \"SMARTHOST\" )\n                        Display --indent 4 --text \"- Try Verify Hosts\" --result \"${STATUS_ENABLED}\" --color YELLOW\n                        ;;\n                esac\n            else\n                LogText \"Result: Try Verify Hosts not enabled\"\n                Display --indent 4 --text \"- Try Verify Hosts\" --result \"${STATUS_DISABLED}\" --color WHITE\n            fi\n\n            LogText \"Test: Exim Verify Hosts\"\n            if [ -n \"${EXIM_VERIFY_HOSTS}\" ]; then\n                LogText \"Result: Verify Hosts enabled\"\n                case \"${EXIM_TYPE}\" in\n                    \"INTERNET HOST\" )\n                        Display --indent 4 --text \"- Verify Hosts\" --result \"${STATUS_ENABLED}\" --color YELLOW\n                        ;;\n                    \"SATELLITE\" | \"SMARTHOST\" )\n                        Display --indent 4 --text \"- Verify Hosts\" --result \"${STATUS_ENABLED}\" --color GREEN\n                        ;;\n                esac\n            else\n                LogText \"Result: Verify Hosts not enabled\"\n                Display --indent 4 --text \"- Verify Hosts\" --result \"${STATUS_DISABLED}\" --color WHITE\n            fi\n        fi\n    fi\n\n#\n#################################################################################\n#\n    # Test        : MAIL-8814\n    # Description : Check Postfix process\n    # Notes       : qmgr and pickup run under postfix uid, without full path to binary\n    Register --test-no MAIL-8814 --weight L --network NO --category security --description \"Check postfix process status\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: check Postfix status\"\n        # Some other processes also use master, therefore it should include both master and postfix\n        FIND1=$(${PSBINARY} ax | ${GREPBINARY} \"master\" | ${GREPBINARY} \"postfix\" | ${GREPBINARY} -v \"grep\")\n        if [ -n \"${FIND1}\" ]; then\n            LogText \"Result: found running Postfix process\"\n            Display --indent 2 --text \"- Postfix status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            POSTFIX_RUNNING=1\n            SMTP_DAEMON=\"postfix\"\n            Report \"smtp_daemon[]=postfix\"\n        else\n            LogText \"Result: no running Postfix processes found\"\n            if IsVerbose; then Display --indent 2 --text \"- Postfix status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8816\n    # Description : Check Postfix configuration\n    if [ ${POSTFIX_RUNNING} -eq 1 -a ! \"${POSTFIXBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MAIL-8816 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Postfix configuration\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        Display --indent 4 --text \"- Postfix configuration\" --result \"${STATUS_FOUND}\" --color GREEN\n        POSTFIX_CONFIGDIR=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^config_directory' | ${AWKBINARY} '{ print $3 }')\n        POSTFIX_CONFIGFILE=\"${POSTFIX_CONFIGDIR}/main.cf\"\n        LogText \"Postfix configuration directory: ${POSTFIX_CONFIGDIR}\"\n        LogText \"Postfix configuration file: ${POSTFIX_CONFIGFILE}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8817\n    # Description : Check Postfix configuration for error\n    if [ ${POSTFIX_RUNNING} -eq 1 -a ! \"${POSTFIXBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MAIL-8817 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Postfix configuration errors\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: using postconf to see if Postfix configuration has errors\"\n        FIND=$(${POSTCONFBINARY} 2>&1 | ${GREPBINARY} \"warning:\")\n        if [ -n \"${FIND}\" ]; then\n            Report \"postfix_config_error=1\"\n            Display --indent 6 --text \"- Postfix configuration errors\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: found an error or warning in the Postfix configuration. Manual check suggested.\"\n            ReportSuggestion \"${TEST_NO}\" \"Found a configuration error in Postfix\" \"${POSTFIX_CONFIGFILE}\" \"text:run postconf > /dev/null\"\n        else\n            LogText \"Result: all looks to be fine with Postfix configuration\"\n            if IsVerbose; then Display --indent 6 --text \"- Postfix configuration errors\" --result \"${STATUS_OK}\" --color GREEN; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8818\n    # Description : Check Postfix configuration\n    if [ ${POSTFIX_RUNNING} -eq 1 -a ! \"${POSTFIXBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MAIL-8818 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Postfix configuration: banner\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: Checking Postfix banner\"\n        FIND1=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} 'postfix')\n        FIND2=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} '$mail_name')\n        FIND3=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^mail_name' | ${GREPBINARY} -i 'postfix')\n        FIND4=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} -i \"${OS}\")\n        if [ -n \"${LINUX_VERSION}\" ]; then\n            FIND5=$(${POSTCONFBINARY} 2> /dev/null | ${GREPBINARY} '^smtpd_banner' | ${GREPBINARY} -i \"${LINUX_VERSION}\")\n        fi\n        SHOWWARNING=0\n\n        if [ -n \"${FIND1}\" ]; then\n            SHOWWARNING=1\n            Report \"banner_software_disclosure[]=${FIND1}\"\n        elif [ -n \"${FIND2}\" -a -n \"${FIND3}\" ]; then\n            SHOWWARNING=1\n            Report \"banner_software_disclosure[]=${FIND2}\"\n        elif [ -n \"${FIND4}\" ]; then\n            SHOWWARNING=1\n            Report \"banner_os_disclosure[]=${FIND4}\"\n        elif [ -n \"${FIND5}\" ]; then\n            SHOWWARNING=1\n            Report \"banner_os_disclosure[]=${FIND5}\"\n        fi\n\n        if [ ${SHOWWARNING} -eq 1 ]; then\n            Display --indent 6 --text \"- Postfix banner\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: found OS, or mail_name in SMTP banner, and/or mail_name contains 'Postfix'.\"\n            ReportWarning \"${TEST_NO}\" \"Found some information disclosure in SMTP banner (OS or software name)\"\n            ReportSuggestion \"${TEST_NO}\" \"You are advised to hide the mail_name (option: smtpd_banner) from your postfix configuration. Use postconf -e or change your main.cf file (${POSTFIX_CONFIGFILE})\"\n        else\n            if IsVerbose; then Display --indent 6 --text \"- Postfix banner\" --result \"${STATUS_OK}\" --color GREEN; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8820\n    Register --test-no MAIL-8820 --weight L --network NO --category security --description \"Postfix configuration scan\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        if [ \"$(postconf -h inet_interfaces 2> /dev/null)\" = \"all\" ]; then\n            if ! SkipAtomicTest \"${TEST_NO}:disable_vrfy_command\"; then\n                if [ \"$(postconf -h disable_vrfy_command 2> /dev/null)\" = \"no\" ]; then\n                    ReportSuggestion \"${TEST_NO}:disable_vrfy_command\" \"Disable the 'VRFY' command\" \"disable_vrfy_command=no\" \"text:run postconf -e disable_vrfy_command=yes to change the value\"\n                fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8838\n    # Description : Check Dovecot process\n    Register --test-no MAIL-8838 --weight L --network NO --category security --description \"Check dovecot process\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: check dovecot status\"\n        if IsRunning \"dovecot\"; then\n            LogText \"Result: found running dovecot process\"\n            Display --indent 2 --text \"- Dovecot status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            DOVECOT_RUNNING=1\n            IMAP_DAEMON=\"dovecot\"\n            POP3_DAEMON=\"dovecot\"\n            Report \"pop3_daemon[]=dovecot\"\n            Report \"imap_daemon[]=dovecot\"\n        else\n            LogText \"Result: dovecot not found\"\n            if IsVerbose; then Display --indent 2 --text \"- Dovecot status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8860\n    # Description : Check Qmail process status\n    Register --test-no MAIL-8860 --weight L --network NO --category security --description \"Check Qmail status\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: check Qmail status\"\n        if IsRunning \"qmail-smtpd\"; then\n            LogText \"Result: found running Qmail process\"\n            Display --indent 2 --text \"- Qmail status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            QMAIL_RUNNING=1\n            SMTP_DAEMON=\"qmail\"\n            Report \"smtp_daemon[]=qmail\"\n        else\n            LogText \"Result: no running Qmail processes found\"\n            if IsVerbose; then Display --indent 2 --text \"- Qmail status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8880\n    # Description : Check Sendmail process status\n    Register --test-no MAIL-8880 --weight L --network NO --category security --description \"Check Sendmail status\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: check sendmail status\"\n        if IsRunning \"sendmail\"; then\n            LogText \"Result: found running Sendmail process\"\n            Display --indent 2 --text \"- Sendmail status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            SENDMAIL_RUNNING=1\n            SMTP_DAEMON=\"sendmail\"\n            Report \"smtp_daemon[]=sendmail\"\n        else\n            LogText \"Result: no running Sendmail processes found\"\n            if IsVerbose; then Display --indent 2 --text \"- Sendmail status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MAIL-8920\n    # Description : Check OpenSMTPD process status\n    if [ -n \"${SMTPCTLBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MAIL-8920 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check OpenSMTPD status\"\n    if [ ${SKIPTEST} -eq 0  ]; then\n        LogText \"Test: check smtpd status\"\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} -E \"(/smtpd|smtpd: \\[priv\\]|smtpd: smtp)\" | ${GREPBINARY} -v \"grep\")\n        if [ ! \"${FIND}\" = \"\" ]; then\n            LogText \"Result: found running smtpd process\"\n            Display --indent 2 --text \"- OpenSMTPD status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            OPENSMTPD_RUNNING=1\n            Report \"smtp_daemon[]=opensmtpd\"\n        else\n            LogText \"Result: smtpd not found\"\n            if IsVerbose; then Display --indent 2 --text \"- OpenSMTPD status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n\nReport \"imap_daemon=${IMAP_DAEMON}\"\nReport \"pop3_daemon=${POP3_DAEMON}\"\nReport \"smtp_daemon=${SMTP_DAEMON}\"\n\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_malware",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Malware scanners\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_MALWARE}\"\n#\n#################################################################################\n#\n    AVAST_DAEMON_RUNNING=0\n    AVIRA_DAEMON_RUNNING=0\n    BITDEFENDER_DAEMON_RUNNING=0\n    CLAMD_RUNNING=0\n    CLAMSCAN_INSTALLED=0\n    CROWDSTRIKE_FALCON_SENSOR_RUNNING=0\n    ESET_DAEMON_RUNNING=0\n    FRESHCLAM_DAEMON_RUNNING=0\n    KASPERSKY_SCANNER_RUNNING=0\n    MCAFEE_SCANNER_RUNNING=0\n    MALWARE_SCANNER_INSTALLED=0\n    MALWARE_DAEMON_RUNNING=0\n    ROOTKIT_SCANNER_FOUND=0\n    SENTINELONE_SCANNER_RUNNING=0\n    SOPHOS_SCANNER_RUNNING=0\n    SYMANTEC_SCANNER_RUNNING=0\n    SYNOLOGY_DAEMON_RUNNING=0\n    TRENDMICRO_DSA_DAEMON_RUNNING=0\n    WAZUH_DAEMON_RUNNING=0\n#\n#################################################################################\n#\n    # Test        : MALW-3274\n    # Description : Check for installed tool (McAfee VirusScan for Command Line)\n    Register --test-no MALW-3274 --weight L --network NO --category security --description \"Check for McAfee VirusScan Command Line\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking presence McAfee VirusScan for Command Line\"\n        if [ -x /usr/local/uvscan/uvscan ]; then\n            Display --indent 2 --text \"- ${GEN_CHECKING} McAfee VirusScan for Command Line (deprecated)\" --result \"${STATUS_FOUND}\" --color RED\n            LogText \"Result: Found ${MCAFEECLBINARY}\"\n            AddHP 0 2\n            LogText \"Result: McAfee Antivirus for Linux has been deprecated as of 1 Oct 2023 and will not receive updates. Please use another antivirus instead.\"\n       fi\n    fi\n#################################################################################\n#\n    # Test        : MALW-3275\n    # Description : Check for installed tool (chkrootkit)\n    Register --test-no MALW-3275 --weight L --network NO --category security --description \"Check for chkrootkit\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking presence chkrootkit\"\n        if [ -n \"${CHKROOTKITBINARY}\" ]; then\n            Display --indent 2 --text \"- ${GEN_CHECKING} chkrootkit\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found ${CHKROOTKITBINARY}\"\n            MALWARE_SCANNER_INSTALLED=1\n            ROOTKIT_SCANNER_FOUND=1\n            AddHP 2 2\n            Report \"malware_scanner[]=chkrootkit\"\n        else\n            LogText \"Result: chkrootkit not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3276\n    # Description : Check for installed tool (Rootkit Hunter)\n    Register --test-no MALW-3276 --weight L --network NO --category security --description \"Check for Rootkit Hunter\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking presence Rootkit Hunter\"\n        if [ -n \"${RKHUNTERBINARY}\" ]; then\n            Display --indent 2 --text \"- ${GEN_CHECKING} Rootkit Hunter\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found ${RKHUNTERBINARY}\"\n            MALWARE_SCANNER_INSTALLED=1\n            ROOTKIT_SCANNER_FOUND=1\n            AddHP 2 2\n            Report \"malware_scanner[]=rkhunter\"\n        else\n            LogText \"Result: Rootkit Hunter not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3278\n    # Description : Check for installed tool (Linux Malware Detect or LMD)\n    Register --test-no MALW-3278 --weight L --network NO --category security --description \"Check for LMD\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking presence LMD\"\n        if [ ! \"${LMDBINARY}\" = \"\" ]; then\n            Display --indent 2 --text \"- ${GEN_CHECKING} LMD (Linux Malware Detect)\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found ${LMDBINARY}\"\n            MALWARE_SCANNER_INSTALLED=1\n            AddHP 2 2\n            Report \"malware_scanner[]=lmd\"\n        else\n            LogText \"Result: LMD not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3280\n    # Description : Check if an anti-virus tool is installed\n    Register --test-no MALW-3280 --weight L --network NO --category security --description \"Check if anti-virus tool is installed\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n\n        # Avast (macOS)\n        LogText \"Test: checking process com.avast.daemon\"\n        if IsRunning --full \"com.avast.daemon\"; then\n            FOUND=1\n            AVAST_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Avast daemon\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Avast security product\"\n            Report \"malware_scanner[]=avast\"\n        fi\n\n        # Avira\n        LogText \"Test: checking process Avira daemon\"\n        if IsRunning \"avqmd\"; then\n            FOUND=1\n            AVIRA_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Avira daemon\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Avira security product\"\n            Report \"malware_scanner[]=avira\"\n        fi\n\n        # Bitdefender (macOS & Linux)\n        LogText \"Test: checking process Bitdefender daemon\"\n        if IsRunning \"bdagentd\" || IsRunning \"epagd\" || IsRunning \"bdsecd\"; then\n            FOUND=1\n            BITDEFENDER_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Bitdefender daemon\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Bitdefender security product\"\n            Report \"malware_scanner[]=bitdefender\"\n        fi\n\n        # CrowdStrike falcon-sensor\n        LogText \"Test: checking process falcon-sensor (CrowdStrike)\"\n        if IsRunning \"falcon-sensor\"; then\n            FOUND=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} falcon-sensor\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found falcon-sensor service\"\n            CROWDSTRIKE_FALCON_SENSOR_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=falcon-sensor\"\n        fi\n\n        # Cylance (macOS)\n        LogText \"Test: checking process CylanceSvc\"\n        if IsRunning \"CylanceSvc\"; then\n            FOUND=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} CylancePROTECT\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found CylancePROTECT service\"\n            AVAST_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=cylance-protect\"\n        fi\n\n        # ESET security products\n        LogText \"Test: checking process esets_daemon or oaeventd (ESET)\"\n        if IsRunning \"esets_daemon\" || IsRunning \"oaeventd\"; then\n            FOUND=1\n            ESET_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} ESET daemon\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found ESET security product\"\n            Report \"malware_scanner[]=eset\"\n        fi\n\n        # Kaspersky products\n        LogText \"Test: checking process wdserver or klnagent (Kaspersky)\"\n        # wdserver is too generic to match on, so we want to ensure that it is related to Kaspersky first\n        if [ -x /opt/kaspersky/kesl/libexec/kesl_launcher.sh ]; then\n            if IsRunning \"wdserver\"; then KASPERSKY_SCANNER_RUNNING=1; fi\n        else\n            if IsRunning \"klnagent\"; then KASPERSKY_SCANNER_RUNNING=1; fi\n        fi\n        if [ ${KASPERSKY_SCANNER_RUNNING} -eq 1 ]; then\n            FOUND=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Kaspersky\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: Found Kaspersky\"\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=kaspersky\"\n        fi\n\n        # McAfee products\n        LogText \"Test: checking process cma or cmdagent (McAfee)\"\n        # cma is too generic to match on, so we want to ensure that it is related to McAfee first\n        if [ -x /opt/McAfee/cma/bin/cma ]; then\n            if IsRunning \"cma\"; then MCAFEE_SCANNER_RUNNING=1; fi\n        else\n            if IsRunning \"cmdagent\"; then MCAFEE_SCANNER_RUNNING=1; fi\n        fi\n        if [ ${MCAFEE_SCANNER_RUNNING} -eq 1 ]; then\n            FOUND=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} McAfee\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: Found McAfee\"\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=mcafee\"\n        fi\n\n       # SentinelOne\n       LogText \"Text: checking process sentineld (SentinelOne)\"\n       if IsRunning \"sentineld\"; then SENTINELONE_SCANNER_RUNNING=1; fi # macOS\n       if IsRunning \"s1-agent\"; then SENTINELONE_SCANNER_RUNNING=1; fi # Linux\n       if IsRunning \"SentinelAgent\"; then SENTINELONE_SCANNER_RUNNING=1; fi # Windows\n       if [ ${SENTINELONE_SCANNER_RUNNING} -eq 1 ]; then\n            FOUND=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} SentinelOne\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: Found SentinelOne\"\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=sentinelone\"\n        fi\n\n        # Sophos savscand/SophosScanD\n        LogText \"Test: checking process savscand\"\n        if IsRunning \"savscand\"; then\n            FOUND=1\n            SOPHOS_SCANNER_RUNNING=1\n        fi\n        LogText \"Test: checking process SophosScanD\"\n        if IsRunning \"SophosScanD\"; then\n            FOUND=1\n            SOPHOS_SCANNER_RUNNING=1\n        fi\n        if [ ${SOPHOS_SCANNER_RUNNING} -eq 1 ]; then\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Sophos\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: Found Sophos\"\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=sophos\"\n        fi\n\n        # Symantec rtvscand/smcd/symcfgd\n        LogText \"Test: checking process rtvscand\"\n        if IsRunning \"rtvscand\"; then\n            SYMANTEC_SCANNER_RUNNING=1\n        fi\n        LogText \"Test: checking process Symantec management client service\"\n        if IsRunning \"smcd\"; then\n            SYMANTEC_SCANNER_RUNNING=1\n        fi\n        LogText \"Test: checking process Symantec Endpoint Protection configuration service\"\n        if IsRunning \"symcfgd\"; then\n            SYMANTEC_SCANNER_RUNNING=1\n        fi\n        if [ ${SYMANTEC_SCANNER_RUNNING} -eq 1 ]; then\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Symantec\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found one or more Symantec components\"\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            FOUND=1\n            Report \"malware_scanner[]=symantec\"\n        fi\n\n        # Synology Antivirus Essential\n        LogText \"Test: checking process synoavd\"\n        if IsRunning \"synoavd\"; then\n            FOUND=1\n            SYNOLOGY_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Synology Antivirus Essential\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Synology Antivirus Essential\"\n            Report \"malware_scanner[]=synoavd\"\n        fi\n\n        # Trend Micro Anti Malware for Linux\n        # Typically ds_agent is running as well, the Deep Security Agent\n        LogText \"Test: checking process ds_agent to test for Trend Micro Deep Anti Malware component\"\n        if IsRunning \"ds_am\"; then\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Trend Micro Anti Malware\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Trend Micro Anti Malware component\"\n            FOUND=1\n            MALWARE_SCANNER_INSTALLED=1\n            MALWARE_DAEMON_RUNNING=1\n            TRENDMICRO_DSA_DAEMON_RUNNING=1\n            Report \"malware_scanner[]=trend-micro-am\"\n        fi\n\n        # TrendMicro (macOS)\n        LogText \"Test: checking process TmccMac to test for Trend Micro anti-virus (macOS)\"\n        if IsRunning \"TmccMac\"; then\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Trend Micro anti-virus\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Trend Micro component\"\n            FOUND=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            Report \"malware_scanner[]=trend-micro-av\"\n        fi\n\n        # Wazuh agent\n        LogText \"Test: checking process wazuh-agent to test for Wazuh agent\"\n        if IsRunning \"wazuh-agentd\"; then\n            if IsVerbose; then Display --indent 2 --text \"- ${GEN_CHECKING} Wazuh agent\" --result \"${STATUS_FOUND}\" --color GREEN; fi\n            LogText \"Result: found Wazuh component\"\n            FOUND=1\n            WAZUH_DAEMON_RUNNING=1\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            ROOTKIT_SCANNER_FOUND=1\n            Report \"malware_scanner[]=wazuh\"\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: no commercial anti-virus tools found\"\n            AddHP 0 3\n        else\n            LogText \"Result: found one or more commercial anti-virus tools\"\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3282\n    # Description : Check if clamscan is installed\n    Register --test-no MALW-3282 --weight L --network NO --category security --description \"Check for clamscan\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking presence clamscan\"\n        if [ ! \"${CLAMSCANBINARY}\" = \"\" ]; then\n            Display --indent 2 --text \"- Checking ClamAV scanner\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found ${CLAMSCANBINARY}\"\n            MALWARE_SCANNER_INSTALLED=1\n            CLAMSCAN_INSTALLED=1\n            AddHP 2 2\n        else\n            LogText \"Result: clamscan couldn't be found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3284\n    # Description : Check running clamd process\n    Register --test-no MALW-3284 --weight L --network NO --category security --description \"Check for clamd\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking running ClamAV daemon (clamd)\"\n        if IsRunning \"clamd\"; then\n            Display --indent 2 --text \"- ${GEN_CHECKING} ClamAV daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: found running clamd process\"\n            MALWARE_DAEMON_RUNNING=1\n            MALWARE_SCANNER_INSTALLED=1\n            CLAMD_RUNNING=1\n        else\n            LogText \"Result: clamd not running\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3291\n    # Description : Check if Microsoft Defender Antivirus is installed\n    Register --test-no MALW-3291 --weight L --network NO --category security --description \"Check for mdatp\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking presence mdatp\"\n        if [ ! \"${MDATPBINARY}\" = \"\" ]; then\n            Display --indent 2 --text \"- Checking Microsoft Defender Antivirus\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found ${MDATPBINARY}\"\n            MALWARE_SCANNER_INSTALLED=1\n            AddHP 2 2\n            Report \"malware_scanner[]=mdatp\"\n        else\n            LogText \"Result: mdatp couldn't be found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3286\n    # Description : Check running freshclam if clamd process is running\n    if [ ${CLAMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MALW-3286 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for freshclam\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking running freshclam daemon\"\n        if IsRunning \"freshclam\"; then\n            FRESHCLAM_DAEMON_RUNNING=1\n            Display --indent 4 --text \"- ${GEN_CHECKING} freshclam\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: found running freshclam process\"\n            AddHP 2 2\n        else\n            Display --indent 4 --text \"- ${GEN_CHECKING} freshclam\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: freshclam is not running\"\n            ReportSuggestion \"${TEST_NO}\" \"Confirm that freshclam is properly configured and keeps updating the ClamAV database\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3288\n    # Description : Check for ClamXav (macOS)\n    if [ -d /Applications/ClamXav.app/Contents/Resources/ScanningEngine/bin/ ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no MALW-3288 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for ClamXav\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        CLAMSCANBINARY=$(${LSBINARY} /Applications/ClamXav.app/Contents/Resources/ScanningEngine/bin/ 2> /dev/null | ${GREPBINARY} 'clamscan')\n        if [ -n \"${CLAMSCANBINARY}\" ]; then\n            LogText \"Result: Found ClamXav clamscan installed\"\n            Display --indent 2 --text \"- ${GEN_CHECKING} ClamXav AV scanner\" --result \"${STATUS_FOUND}\" --color GREEN\n            MALWARE_SCANNER_INSTALLED=1\n            CLAMSCAN_INSTALLED=1\n            AddHP 3 3\n        else\n            LogText \"Result: ClamXav malware scanner not found\"\n            AddHP 0 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Check if we found any of the ClamAV components\n    if [ ${CLAMSCAN_INSTALLED} -eq 1 -o ${CLAMD_RUNNING} -eq 1 -o ${FRESHCLAM_DAEMON_RUNNING} -eq 1 ]; then\n        Report \"malware_scanner[]=clamav\"\n    fi\n#\n#################################################################################\n#\n    # Test        : MALW-3290\n    # Description : Presence of malware scanners\n    Register --test-no MALW-3290 --weight L --network NO --category security --description \"Presence of for malware detection\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${MALWARE_SCANNER_INSTALLED} -eq 0 ]; then\n            Display --indent 2 --text \"- Malware software components\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        else\n            Display --indent 2 --text \"- Malware software components\" --result \"${STATUS_FOUND}\" --color GREEN\n            if [ ${MALWARE_DAEMON_RUNNING} -eq 0 ]; then\n                Display --indent 4 --text \"- Active agent\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            else\n                Display --indent 4 --text \"- Active agent\" --result \"${STATUS_FOUND}\" --color GREEN\n            fi\n            if [ ${ROOTKIT_SCANNER_FOUND} -eq 0 ]; then\n                Display --indent 4 --text \"- Rootkit scanner\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            else\n                Display --indent 4 --text \"- Rootkit scanner\" --result \"${STATUS_FOUND}\" --color GREEN\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n\n\n\nReport \"malware_scanner_installed=${MALWARE_SCANNER_INSTALLED}\"\n\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_memory_processes",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Memory and processes\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_MEMORY_AND_PROCESSES}\"\n#\n#################################################################################\n#\n    # Test        : PROC-3602\n    # Description : Query /proc/meminfo\n    Register --test-no PROC-3602 --os Linux --weight L --network NO --category security --description \"Checking /proc/meminfo for memory details\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -f ${ROOTDIR}proc/meminfo ]; then\n            LogText \"Result: found ${ROOTDIR}proc/meminfo\"\n            Display --indent 2 --text \"- Checking ${ROOTDIR}proc/meminfo\" --result \"${STATUS_FOUND}\" --color GREEN\n            FIND=$(${AWKBINARY} '/^MemTotal/ { print $2, $3 }' ${ROOTDIR}proc/meminfo)\n            MEMORY_SIZE=$(echo ${FIND} | ${AWKBINARY} '{ print $1 }')\n            MEMORY_UNITS=$(echo ${FIND} | ${AWKBINARY} '{ print $2 }')\n            LogText \"Result: Found ${MEMORY_SIZE} ${MEMORY_UNITS} memory\"\n            Report \"memory_size=${MEMORY_SIZE}\"\n            Report \"memory_units=${MEMORY_UNITS}\"\n        else\n            LogText \"Result: ${ROOTDIR}proc/meminfo file not found on this system\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PROC-3604\n    # Description : Query /proc/meminfo\n    # Notes       : TODO - prtconf replacement\n    Register --test-no PROC-3604 --os Solaris --weight L --network NO --category security --description \"Query prtconf for memory details\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching /usr/sbin/prtconf\"\n        if [ -x /usr/sbin/prtconf ]; then\n            Display --indent 2 --text \"- Querying prtconf for installed memory\" --result \"${STATUS_DONE}\" --color GREEN\n            MEMORY_SIZE=$(/usr/sbin/prtconf | ${GREPBINARY} \"^Memory size:\" | ${CUTBINARY} -d ' ' -f3)\n            MEMORY_UNITS=$(/usr/sbin/prtconf | ${GREPBINARY} \"^Memory size:\" | ${CUTBINARY} -d ' ' -f4)\n            LogText \"Result: Found ${MEMORY_SIZE} ${MEMORY_UNITS} memory\"\n            Report \"memory_size=${MEMORY_SIZE}\"\n            Report \"memory_units=${MEMORY_UNITS}\"\n        else\n            Display --indent 2 --text \"- Querying prtconf for installed memory\" --result \"${STATUS_SKIPPED}\" --color WHITE\n            LogText \"Result: /usr/sbin/prtconf not found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PROC-3612\n    # Description : Searching for dead and zombie processes\n    # Notes       : Don't perform test on Solaris\n    if [ ! \"${OS}\" = \"Solaris\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PROC-3612 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check dead or zombie processes\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ \"${OS}\" = \"AIX\" ]; then\n            FIND=$(${PSBINARY} -Ae -o pid,stat,comm | ${AWKBINARY} '{ if ($2 ~ /Z|X/) print $1 }' | ${XARGSBINARY})\n        else\n            FIND=$(${PSBINARY} x -o pid,stat,comm | ${AWKBINARY} '{ if ($2 ~ /Z|X/) print $1 }' | ${XARGSBINARY})\n        fi\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: no zombie processes found\"\n            Display --indent 2 --text \"- Searching for dead/zombie processes\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        else\n            LogText \"Result: found one or more dead or zombie processes\"\n            LogText \"Output: PIDs ${FIND}\"\n            Display --indent 2 --text \"- Searching for dead/zombie processes\" --result \"${STATUS_FOUND}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check the output of ps for dead or zombie processes\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PROC-3614\n    # Description : Searching for heavy IO based waiting processes\n    # Notes       : Don't perform test on Solaris\n    if [ ! \"${OS}\" = \"Solaris\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PROC-3614 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check heavy IO waiting based processes\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ \"${OS}\" = \"AIX\" ]; then\n            FIND=$(${PSBINARY} -Ae -o pid,stat,comm | ${AWKBINARY} '{ if ($2==\"D\") print $1 }' | ${XARGSBINARY})\n        else\n            FIND=$(${PSBINARY} x -o pid,stat,comm | ${AWKBINARY} '{ if ($2==\"D\") print $1 }' | ${XARGSBINARY})\n        fi\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: No processes were waiting for IO requests to be handled first\"\n            Display --indent 2 --text \"- Searching for IO waiting processes\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        else\n            LogText \"Result: found one or more processes which were waiting to get IO requests handled first\"\n            LogText \"More info: processes which show up with the status flag 'D' are often stuck, until a disk IO event finished. This can happen for example with network storage, where the connection or protocol settings are not logtext well configured.\"\n            LogText \"Output: PIDs ${FIND}\"\n            Display --indent 2 --text \"- Searching for IO waiting processes\" --result \"${STATUS_FOUND}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check process listing for processes waiting for IO requests\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PROC-3802\n    # Description : Check presence of prelink tooling\n    Register --test-no PROC-3802 --package-manager-required --os Linux --weight L --network NO --category security --description \"Check presence of prelink tooling\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if PackageIsInstalled \"prelink\"; then\n            LogText \"Result: prelink packages is installed\"\n            # TODO\n            # - Add item to website with rationale\n            #ReportSuggestion \"${TEST_NO}\" \"Disable and remove prelinking of binaries\"\n            AddHP 1 3\n            Display --indent 2 --text \"- Search prelink tooling\" --result \"${STATUS_FOUND}\" --color YELLOW\n        else\n            Display --indent 2 --text \"- Search prelink tooling\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n            LogText \"Result: prelink package is NOT installed\"\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_nameservices",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Name services\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_NAME_SERVICES}\"\n#\n#################################################################################\n#\n    BIND_RUNNING=0\n    BIND_CONFIG_LOCS=\"${ROOTDIR}etc ${ROOTDIR}etc/bind ${ROOTDIR}usr/local/etc ${ROOTDIR}usr/local/etc/namedb\"\n    BIND_CONFIG_LOCATION=\"\"\n    POWERDNS_RUNNING=0\n    POWERDNS_CONFIG_LOCS=\"${ROOTDIR}etc/powerdns ${ROOTDIR}usr/local/etc\"\n    POWERDNS_AUTH_CONFIG_LOCATION=\"\"\n    POWERDNS_AUTH_MASTER=0\n    POWERDNS_AUTH_SLAVE=0\n    UNBOUND_CONFIG_OK=0\n    YPBIND_RUNNING=0\n#\n#################################################################################\n#\n    # Test        : NAME-4016\n    # Description : Check main domain (domain <domain name> in /etc/resolv.conf)\n    Register --test-no NAME-4016 --weight L --network NO --category security --description \"Check /etc/resolv.conf default domain\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check ${ROOTDIR}etc/resolv.conf for default domain\"\n        if [ -f ${ROOTDIR}etc/resolv.conf ]; then\n            LogText \"Result: ${ROOTDIR}etc/resolv.conf found\"\n            FIND=$(${AWKBINARY} '/^domain/ { print $2 }' ${ROOTDIR}etc/resolv.conf)\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: no default domain found\"\n                if IsVerbose; then Display --indent 2 --text \"- Checking default DNS search domain\" --result \"${STATUS_NONE}\" --color WHITE; fi\n            else\n                LogText \"Result: found default domain\"\n                LogText \"Output: ${FIND}\"\n                Report \"resolv_conf_domain=${FIND}\"\n                Display --indent 2 --text \"- Checking default DNS search domain\" --result \"${STATUS_FOUND}\" --color GREEN\n                RESOLV_DOMAINNAME=\"${FIND}\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4018\n    # Description : Check search domains in /etc/resolv.conf\n    # Notes       : Maximum of one search keyword is allowed in /etc/resolv.conf\n    Register --test-no NAME-4018 --weight L --network NO --category security --description \"Check /etc/resolv.conf search domains\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: check ${ROOTDIR}etc/resolv.conf for search domains\"\n        if [ -f ${ROOTDIR}etc/resolv.conf ]; then\n            LogText \"Result: ${ROOTDIR}etc/resolv.conf found\"\n            FIND=$(${AWKBINARY} '/^search/ { print $2 }' ${ROOTDIR}etc/resolv.conf)\n            if IsEmpty \"${FIND}\"; then\n                LogText \"Result: no search domains found, default domain is being used\"\n            else\n                for ITEM in ${FIND}; do\n                    LogText \"Found search domain: ${ITEM}\"\n                    Report \"resolv_conf_search_domain[]=${ITEM}\"\n                    COUNT=$((COUNT + 1))\n                done\n                # Warn if we have more than 6 search domains, which is maximum in most resolvers\n                if [ ${COUNT} -gt 6 ]; then\n                    LogText \"Result: Found ${COUNT} search domains\"\n                    Display --indent 2 --text \"- Checking search domains\" --result \"${STATUS_WARNING}\" --color YELLOW\n                    ReportWarning \"${TEST_NO}\" \"Found more than 6 search domains, which is usually more than the maximum allowed number in most resolvers\"\n                else\n                    LogText \"Result: Found ${COUNT} search domains\"\n                    Display --indent 2 --text \"- Checking search domains\" --result \"${STATUS_FOUND}\" --color GREEN\n                fi\n            fi\n            # Check amount of search domains (max 1)\n            FIND=$(${GREPBINARY} -c \"^search\" ${ROOTDIR}etc/resolv.conf)\n            if [ ! \"${FIND}\" = \"0\" -a ! \"${FIND}\" = \"1\" ]; then\n                LogText \"Result: found ${FIND} line(s) with a search statement (expecting less than 2 lines)\"\n                Display --indent 4 --text \"- Checking search domains lines\" --result \"CONFIG ERROR\" --color YELLOW\n                ReportWarning \"${TEST_NO}\" \"Found more than 1 search lines in /etc/resolv.conf, which is probably a misconfiguration\"\n            else\n                LogText \"Result: found ${FIND} line(s) with a search statement (expecting less than 2 lines)\"\n            fi\n        else\n            LogText \"Result: ${ROOTDIR}etc/resolv.conf does not exist, skipping test\"\n            Display --indent 2 --text \"- Checking search domains\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4020\n    # Description : Check non default resolv.conf options\n    Register --test-no NAME-4020 --weight L --network NO --category security --description \"Check non default options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check ${ROOTDIR}etc/resolv.conf for non default options\"\n        if [ -f ${ROOTDIR}etc/resolv.conf ]; then\n            LogText \"Result: ${ROOTDIR}etc/resolv.conf found\"\n            FIND=$(${GREPBINARY} \"^options\" ${ROOTDIR}etc/resolv.conf | ${AWKBINARY} '{ print $2 }')\n            if IsEmpty \"${FIND}\"; then\n                LogText \"Result: no specific other options configured in /etc/resolv.conf\"\n                if IsVerbose; then Display --indent 2 --text \"- Checking /etc/resolv.conf options\" --result \"${STATUS_NONE}\" --color WHITE; fi\n            else\n                for ITEM in ${FIND}; do\n                    LogText \"Found option: ${ITEM}\"\n                    Report \"resolv_conf_option[]=${ITEM}\"\n                    # TODO add suggestions for the related options\n                    # rotate --> add performance tune point\n                    # timeout --> add performance tune point when smaller than 3 seconds\n                done\n                Display --indent 2 --text \"- Checking /etc/resolv.conf options\" --result \"${STATUS_FOUND}\" --color GREEN\n            fi\n        else\n            LogText \"Result: /etc/resolv.conf not found, test skipped\"\n            Display --indent 2 --text \"- Checking /etc/resolv.conf options\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4024\n    # Description : Check Solaris uname -n output\n    Register --test-no NAME-4024 --os Solaris --weight L --network NO --category security --description \"Solaris uname -n output\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${UNAMEBINARY} -n)\n        LogText \"Result: 'uname -n' returned ${FIND}\"\n        Display --indent 2 --text \"- Checking uname -n output\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4026\n    # Description : Check Solaris /etc/nodename\n    # Notes       : If a system is standalone, /etc/nodename should contain a system name only, not FQDN\n    Register --test-no NAME-4026 --os Solaris --weight L --network NO --category security --description \"Check /etc/nodename\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking /etc/nodename\"\n        if [ -f /etc/nodename ]; then\n            LogText \"Result: file /etc/nodename exists\"\n            FIND=$(cat /etc/nodename)\n            LogText \"Output: ${FIND}\"\n            Display --indent 2 --text \"- Checking /etc/nodename\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            LogText \"Result: file /etc/nodename could not be found\"\n            Display --indent 2 --text \"- Checking /etc/nodename\" --result \"NONE FOUND\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4028\n    # Description : Check DNS domain name\n    # To Do       : ${GREPBINARY} ^DOMAINNAME /etc/conf.d/domainname (remove \"'s)\n    Register --test-no NAME-4028 --weight L --network NO --category security --description \"Check domain name\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        DOMAINNAME=\"\"\n        LogText \"Test: Checking if dnsdomainname command is available\"\n        if HasData \"${DNSDOMAINNAMEBINARY}\"; then\n            FIND2=$(${DNSDOMAINNAMEBINARY} 2> /dev/null)\n            if HasData \"${FIND2}\"; then\n                LogText \"Result: dnsdomainname command returned a value\"\n                LogText \"Found domain name: ${FIND2}\"\n                DOMAINNAME=\"${FIND2}\"\n            else\n                LogText \"Result: dnsdomainname command returned no value\"\n            fi\n        else\n            LogText \"Result: dnsdomainname binary not found, skip specific test\"\n        fi\n\n        # If files and commands can't be found, use defined value from resolv.conf\n        if [ -z \"${DOMAINNAME}\" ]; then\n            if [ -n \"${RESOLV_DOMAINNAME}\" ]; then\n                LogText \"Result: using domain name from ${ROOTDIR}etc/resolv.conf\"\n                DOMAINNAME=${RESOLV_DOMAINNAME}\n            else\n                LogText \"Result: using domain name from FQDN hostname (${FQDN})\"\n                DOMAINNAME=$(echo ${FQDN} | ${AWKBINARY} -F. '{print $2}')\n            fi\n        fi\n\n        if [ -n \"${DOMAINNAME}\" ]; then\n            LogText \"Result: found domain name\"\n            Report \"domainname=${DOMAINNAME}\"\n            Display --indent 2 --text \"- Searching DNS domain name\" --result \"${STATUS_FOUND}\" --color GREEN\n            Display --indent 6 --text \"Domain name: ${DOMAINNAME}\"\n        else\n            Display --indent 2 --text \"- Searching DNS domain name\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Check DNS configuration for the dns domain name\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4032\n    # Description : Check name service caching daemon (NSCD) status\n    Register --test-no NAME-4032 --weight L --network NO --category security --description \"Check nscd status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking nscd status\"\n        if IsRunning \"nscd\"; then\n            NAME_CACHE_USED=1\n            LogText \"Result: nscd is running\"\n            Display --indent 2 --text \"- Checking nscd status\" --result \"${STATUS_RUNNING}\" --color GREEN\n        else\n            LogText \"Result: nscd is not running\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking nscd status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4034\n    # Description : Check name service caching daemon (Unbound) status\n    Register --test-no NAME-4034 --weight L --network NO --category security --description \"Check Unbound status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking Unbound (unbound) status\"\n        if IsRunning \"unbound\"; then\n            UNBOUND_RUNNING=1\n            NAME_CACHE_USED=1\n            LogText \"Result: Unbound daemon is running\"\n            Display --indent 2 --text \"- Checking Unbound status\" --result \"${STATUS_RUNNING}\" --color GREEN\n        else\n            LogText \"Result: Unbound daemon is not running\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking Unbound status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4036\n    # Description : Checking Unbound configuration file\n    if [ ${UNBOUND_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4036 --preqs-met ${PREQS_MET}  --weight L --network NO --category security --description \"Check Unbound configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(which unbound-checkconf | grep -v \"no [^ ]* in \")\n        if [ ! \"${FIND}\" = \"\" ]; then\n            LogText \"Test: running unbound-checkconf\"\n            # Don't capture any output, just gather exit code (0 is fine, otherwise bad)\n            FIND=$(unbound-checkconf > /dev/null 2>&1)\n            if [ $? -eq 0 ]; then\n                UNBOUND_CONFIG_OK=1\n                LogText \"Result: Configuration is fine\"\n                Display --indent 2 --text \"- Checking configuration file\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: Unbound daemon is not running\"\n                Display --indent 2 --text \"- Checking configuration file\" --result \"NOT OK\" --color YELLOW\n                ReportWarning \"${TEST_NO}\" \"Found Unbound configuration file issues (run unbound-checkconf)\"\n            fi\n        else\n            LogText \"Result: skipped, can't find unbound-checkconf utility\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4202\n    # Description : Check if BIND is running\n    Register --test-no NAME-4202 --weight L --network NO --category security --description \"Check BIND status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for running BIND instance\"\n        if IsRunning \"named\"; then\n            LogText \"Result: found BIND process\"\n            Display --indent 2 --text \"- Checking BIND status\" --result \"${STATUS_FOUND}\" --color GREEN\n            BIND_RUNNING=1\n        else\n            LogText \"Result: BIND not running\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking BIND status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4204\n    # Description : Check configuration file of BIND\n    if [ ${BIND_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4204 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Search BIND configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Search BIND configuration file\"\n        for I in ${BIND_CONFIG_LOCS}; do\n            if [ -f ${I}/named.conf ]; then\n                BIND_CONFIG_LOCATION=\"${I}/named.conf\"\n                LogText \"Result: found configuration file (${BIND_CONFIG_LOCATION})\"\n            fi\n        done\n        if [ -n \"${BIND_CONFIG_LOCATION}\" ]; then\n            Display --indent 4 --text \"- Checking BIND configuration file\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            Display --indent 4 --text \"- Checking BIND configuration file\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4206\n    # Description : Check BIND configuration file consistency\n    if [ ${BIND_RUNNING} -eq 1 -a ! \"${BIND_CONFIG_LOCATION}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4206 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check BIND configuration consistency\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching for named-checkconf binary\"\n        if [ ! \"${NAMEDCHECKCONFBINARY}\" = \"\" ]; then\n            LogText \"Result: named-checkconf is installed\"\n            FIND=$(${NAMEDCHECKCONFBINARY} ${BIND_CONFIG_LOCATION}; echo $?)\n            if [ \"${FIND}\" = \"0\" ]; then\n                LogText \"Result: configuration file ${BIND_CONFIG_LOCATION} seems to be fine\"\n                Display --indent 4 --text \"- Checking BIND configuration consistency\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: possible errors found in ${BIND_CONFIG_LOCATION}\"\n                Display --indent 4 --text \"- Checking BIND configuration consistency\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"Errors discovered in BIND configuration file\"\n            fi\n        else\n            LogText \"Result: named-checkconf not found, skipping test\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4210\n    # Description : Check if we can determine useful information from banner\n    if [ ${BIND_RUNNING} -eq 1 -a ! \"${BIND_CONFIG_LOCATION}\" = \"\" -a ! \"${DIGBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4210 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check DNS banner\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Trying to determine version from banner\"\n        FIND=$(${DIGBINARY} @localhost version.bind chaos txt | ${GREPBINARY} \"^version.bind\" | ${GREPBINARY} TXT | ${GREPBINARY} -E \"[0-9].[0-9].[0-9]*\")\n        if [ \"${FIND}\" = \"\" ]; then\n            LogText \"Result: no useful information in banner found\"\n            Display --indent 4 --text \"- Checking BIND version in banner\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        else\n            LogText \"Result: possible BIND version available in version banner\"\n            Display --indent 4 --text \"- Checking BIND version in banner\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Found BIND version in banner\"\n            ReportSuggestion \"${TEST_NO}\" \"The version in BIND can be masked by defining 'version none' in the configuration file\"\n            AddHP 0 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4212 TODO\n    # Description : Check version option in BIND configuration\n    #if [ ${BIND_RUNNING} -eq 1 -a ! \"${BIND_CONFIG_LOCATION}\" = \"\" -a ! \"${DIGBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    #Register --test-no NAME-4212 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check version setting in configuration\"\n#\n#################################################################################\n#\n    # Test        : NAME-4220 TODO\n    # Description : Check if we can perform a zone transfer of primary domain\n    #Register --test-no NAME-4220 --weight L --network NO --category security --description \"Check zone transfer\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n#\n#################################################################################\n#\n    # Test        : NAME-4222 TODO\n    # Description : Check if we can perform a zone transfer of PTR (of primary domain)\n    #Register --test-no NAME-4222 --weight L --network NO --category security --description \"Check zone transfer\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n#\n#################################################################################\n#\n    # Test        : NAME-4230\n    # Description : Check if PowerDNS is running\n    Register --test-no NAME-4230 --weight L --network NO --category security --description \"Check PowerDNS status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for running PowerDNS instance\"\n        if IsRunning \"pdns_server\"; then\n            LogText \"Result: found PowerDNS process\"\n            Display --indent 2 --text \"- Checking PowerDNS status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            POWERDNS_RUNNING=1\n        else\n            LogText \"Result: PowerDNS not running\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking PowerDNS status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4232\n    # Description : Check PowerDNS configuration file\n    if [ ${POWERDNS_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4232 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Search PowerDNS configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Search PowerDNS configuration file\"\n        for DIR in ${POWERDNS_CONFIG_LOCS}; do\n            if [ -f ${DIR}/pdns.conf ]; then\n                POWERDNS_AUTH_CONFIG_LOCATION=\"${DIR}/pdns.conf\"\n                LogText \"Result: found configuration file (${POWERDNS_AUTH_CONFIG_LOCATION})\"\n            fi\n        done\n        if HasData \"${POWERDNS_AUTH_CONFIG_LOCATION}\"; then\n            Display --indent 4 --text \"- Checking PowerDNS configuration file\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            Display --indent 4 --text \"- Checking PowerDNS configuration file\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n#    # Test        : NAME-4234\n#    # Description : Check PowerDNS configuration file consistency\n#    if [ ${POWERDNS_RUNNING} -eq 1 -a ! \"${POWERDNS_AUTH_CONFIG_LOCATION}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n#    Register --test-no NAME-4234 --weight L --network NO --category security --description \"Check PowerDNS configuration consistency\"\n#    if [ ${SKIPTEST} -eq 0 ]; then\n#    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4236\n    # Description : Check PowerDNS server backends\n    if [ ${POWERDNS_RUNNING} -eq 1 -a ! \"${POWERDNS_AUTH_CONFIG_LOCATION}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4236 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PowerDNS backends\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for PowerDNS backends\"\n        FIND=$(${AWKBINARY} -F= '/^launch/ { print $2 }' ${POWERDNS_AUTH_CONFIG_LOCATION})\n        if HasData \"${FIND}\"; then\n            for ITEM in ${FIND}; do\n                LogText \"Found backend: ${ITEM}\"\n            done\n            Display --indent 4 --text \"- Checking PowerDNS backends\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: no PowerDNS backends found\"\n            Display --indent 4 --text \"- Checking PowerDNS backends\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4238\n    # Description : Check PowerDNS authoritative status\n    if [ ${POWERDNS_RUNNING} -eq 1 -a -n \"${POWERDNS_AUTH_CONFIG_LOCATION}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4238 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PowerDNS authoritative status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for PowerDNS master status\"\n        FIND=$(${GREPBINARY} \"^master=yes\" ${POWERDNS_AUTH_CONFIG_LOCATION})\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Found master=yes in configuration file\"\n            Display --indent 4 --text \"- PowerDNS authoritative master: YES\"\n            POWERDNS_AUTH_MASTER=1\n        else\n            LogText \"Result: most likely not master (no master=yes)\"\n            Display --indent 4 --text \"- PowerDNS authoritative master: NO\"\n        fi\n        LogText \"Test: Checking for PowerDNS slave status\"\n        FIND=$(${GREPBINARY} \"^slave=yes\" ${POWERDNS_AUTH_CONFIG_LOCATION})\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Found slave=yes in configuration file\"\n            Display --indent 4 --text \"- PowerDNS authoritative slave: YES\"\n            POWERDNS_AUTH_SLAVE=1\n        else\n            LogText \"Result: most likely not slave (no slave=yes)\"\n            Display --indent 4 --text \"- PowerDNS authoritative slave: NO\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4304\n    # Description : Check NIS ypbind daemon status\n    Register --test-no NAME-4304 --weight L --network NO --category security --description \"Check NIS ypbind status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking status of ypbind daemon\"\n        if IsRunning \"ypbind\"; then\n            LogText \"Result: ypbind is running\"\n            Display --indent 2 --text \"- Checking ypbind status\" --result \"${STATUS_FOUND}\" --color GREEN\n            YPBIND_RUNNING=1\n            if IsRunning \"ypldap\"; then\n                LogText \"Result: ypldap is running\"\n                Display --indent 2 --text \"- Checking ypldap status\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                ReportSuggestion \"${TEST_NO}\" \"Disable the usage of NIS/NIS+ and use an alternative like LDAP or Kerberos instead\"\n            fi\n        else\n            LogText \"Result: ypbind is not active\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking ypbind status\" --result \"${STATUS_NOT_FOUND}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4306\n    # Description : Check NIS domain\n    # Notes       : FreeBSD: sysctl kern.domainname\n    if [ ${YPBIND_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4306 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check NIS domain\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking $(domainname) for NIS domain value\"\n        FIND=$(${DOMAINNAMEBINARY} | ${GREPBINARY} -v \"(none)\")\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Value: ${FIND}\"\n            NISDOMAIN=\"${FIND}\"\n        else\n            LogText \"Result: no NIS domain found in command output\"\n        fi\n        # Solaris / Linux style\n        LogText \"Test: Checking file ${ROOTDIR}etc/defaultdomain\"\n        if [ -f ${ROOTDIR}etc/defaultdomain ]; then\n            LogText \"Result: file ${ROOTDIR}etc/defaultdomain exists\"\n            FIND2=$(cat ${ROOTDIR}etc/defaultdomain)\n            if [ -n \"${FIND2}\" ]; then\n                LogText \"Output: ${FIND2}\"\n                NISDOMAIN=\"${FIND2}\"\n            else\n                LogText \"Result: no NIS domain found in file\"\n            fi\n        fi\n        # Red Hat style\n        LogText \"Test: checking ${ROOTDIR}etc/sysconfig/network\"\n        if [ -f ${ROOTDIR}etc/sysconfig/network ]; then\n            LogText \"Result: file ${ROOTDIR}etc/sysconfig/network exists\"\n            LogText \"Test: checking NISDOMAIN value in file\"\n            FIND3=$(${GREPBINARY} \"^NISDOMAIN\" ${ROOTDIR}etc/sysconfig/network | ${AWKBINARY} -F= '{ print $2 }' | ${SEDBINARY} 's/\"//g')\n            if [ -n \"${FIND3}\" ]; then\n                LogText \"Found NIS domain: ${FIND3}\"\n                NISDOMAIN=\"${FIND3}\"\n            else\n                LogText \"Result: No NIS domain found in file\"\n            fi\n        else\n            LogText \"Result: file ${ROOTDIR}etc/sysconfig/network does not exist\"\n        fi\n\n        if [ ! \"${SYSCTLBINARY}\" = \"\" ]; then\n            # Check sysctl (e.g. FreeBSD)\n            LogText \"Test: checking sysctl for kern.domainname\"\n            FIND=$(${SYSCTLBINARY} -a 2>&1 | ${GREPBINARY} \"^kern.domainname\" | ${AWKBINARY} -F: '{ print $2 }' | ${SEDBINARY} 's/ //g' | ${GREPBINARY} -v \"^$\")\n            if [ ! \"${FIND}\" = \"\" ]; then\n                LogText \"Result: found NIS domain via sysctl\"\n                NISDOMAIN=\"${FIND}\"\n            fi\n        fi\n        # Check if we found any NIS domain\n        if [ -n \"${NISDOMAIN}\" ]; then\n            LogText \"Found NIS domain: ${NISDOMAIN}\"\n            Report \"nisdomain=${NISDOMAIN}\"\n            Display --indent 4 --text \"- Checking NIS domain\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: No NIS domain found\"\n            Display --indent 4 --text \"- Checking NIS domain\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    if [ -f ${ROOTDIR}etc/hosts ]; then\n        Display --indent 2 --text \"- Checking /etc/hosts\"\n    else\n        LogText \"Result: no /etc/hosts file found\"\n    fi\n\n    # Test        : NAME-4402\n    # Description : Check /etc/hosts configuration\n    if [ -f ${ROOTDIR}etc/hosts ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4402 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check duplicate line in /etc/hosts\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check duplicate line in ${ROOTDIR}etc/hosts\"\n        OUTPUT=$(${AWKBINARY} '{ print $1, $2 }' ${ROOTDIR}etc/hosts | ${GREPBINARY} -E -v '^(#|$)' | ${GREPBINARY} -E \"[a-f0-9]\" | ${SORTBINARY} | ${UNIQBINARY} -d)\n        if [ -z \"${OUTPUT}\" ]; then\n            LogText \"Result: OK, no duplicate lines found\"\n            Display --indent 4 --text \"- Duplicate entries in hosts file\" --result \"${STATUS_NONE}\" --color GREEN\n        else\n            LogText \"Found duplicate line: ${OUTPUT}\"\n            LogText \"Result: found duplicate line\"\n            Display --indent 4 --text \"- Duplicate entries in hosts file\" --result \"${STATUS_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Remove duplicate lines in ${ROOTDIR}etc/hosts\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4404\n    # Description : Check /etc/hosts contains an entry for this server name\n    if [ -f ${ROOTDIR}etc/hosts ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4404 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check /etc/hosts contains an entry for this server name\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check /etc/hosts contains an entry for this server name\"\n        if [ -n \"${HOSTNAME}\" ]; then\n            DATA=$(${GREPBINARY} -E -v '^(#|$|^::1\\s|localhost)' ${ROOTDIR}etc/hosts | ${GREPBINARY} -i ${HOSTNAME})\n            if [ -n \"${DATA}\" ]; then\n                LogText \"Result: Found entry for ${HOSTNAME} in ${ROOTDIR}etc/hosts\"\n                Display --indent 4 --text \"- Presence of configured hostname in /etc/hosts\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                LogText \"Result: No entry found for ${HOSTNAME} in ${ROOTDIR}etc/hosts\"\n                Display --indent 4 --text \"- Presence of configured hostname in /etc/hosts\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Add the IP name and FQDN to /etc/hosts for proper name resolving\"\n                LogText \"Risk: No entry for the server name [hostname] in /etc/hosts may cause unexpected performance problems for local connections\"\n            fi\n        else\n            LogText \"Result: Skipping test, no hostname configured\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4406\n    # Description : Check server hostname mapping\n    if [ -n \"${HOSTNAME}\" -a -f ${ROOTDIR}etc/hosts ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NAME-4406 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check server hostname mapping\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check server hostname not locally mapped in ${ROOTDIR}etc/hosts\"\n        DATA=$(${GREPBINARY} -E -v '^(#|$)' ${ROOTDIR}etc/hosts | ${GREPBINARY} -E '^(localhost|::1)\\s' | ${GREPBINARY} -w ${HOSTNAME})\n        if [ -n \"${DATA}\" ]; then\n            LogText \"Result: Found this server hostname mapped to a local address\"\n            LogText \"Output: ${DATA}\"\n            Display --indent 4 --text \"- Hostname mapped to localhost\" --result \"${STATUS_FOUND}\" --color YELLOW\n            LogText \"Information: Linking the hostname to the localhost entry may break some resolving. Split resolving so that localhost resolves back to 127.0.0.1 (and ::1) and the hostname of the machine to the real IP address on the network interface.\"\n            ReportSuggestion \"${TEST_NO}\" \"Split resolving between localhost and the hostname of the system\"\n        else\n            LogText \"Result: this server hostname is not mapped to a local address\"\n            Display --indent 4 --text \"- Hostname mapped to localhost\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NAME-4408\n    # Description : Check localhost entry\n    if [ -n \"${GETENT_BINARY}\" ]; then PREQS_MET=\"YES\"; SKIPREASON=\"No getent binary\"; else PREQS_MET=\"NO\"; SKIPREASON=\"\"; fi\n    Register --test-no NAME-4408 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Check localhost entry\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check server hostname not locally mapped in /etc/hosts\"\n        FIND=$(${GETENT_BINARY} hosts localhost | ${AWKBINARY} '{print $1}' | ${SORTBINARY} | ${TRBINARY} -d '\\n')\n        if [ \"${FIND}\" = \"127.0.0.1\" ]; then\n            LogText \"Result: localhost mapped to 127.0.0.1\"\n            Display --indent 4 --text \"- Localhost mapping to IP address\" --result \"${STATUS_OK}\" --color GREEN\n            Report \"localhost-mapped-to=${FIND}\"\n        elif [ \"${FIND}\" = \"::1\" ]; then\n            LogText \"Result: localhost mapped to ::1\"\n            Display --indent 4 --text \"- Localhost mapping to IP address\" --result \"${STATUS_OK}\" --color GREEN\n            Report \"localhost-mapped-to=${FIND}\"\n        elif [ \"${FIND}\" = \"127.0.0.1::1\" ]; then\n            LogText \"Result: localhost mapped to 127.0.0.1 and ::1\"\n            Display --indent 4 --text \"- Localhost mapping to IP address\" --result \"${STATUS_OK}\" --color GREEN\n            Report \"localhost-mapped-to=${FIND}\"\n        else\n            LogText \"Output: ${FIND}\"\n            LogText \"Result: this server hostname is not mapped to a local address\"\n            Display --indent 4 --text \"- Localhost mapping to IP address\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Information: Ensure that localhost resolves back to 127.0.0.1 (and/or ::1).\"\n            ReportSuggestion \"${TEST_NO}\" \"Split resolving between localhost and the hostname of the system\" \"/etc/hosts\" \"text:Check your localhost line\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nReport \"name_cache_used=${NAME_CACHE_USED}\"\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_networking",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Networking\n#\n#################################################################################\n#\n    FOUNDPROMISC=0                                  # Promiscuous interfaces\n    LOCAL_DNSRESOLVER_FOUND=0                       # Local DNS resolver\n    NUMBERACTIVENS=0                                # Number of active nameservers\n    DHCP_CLIENT_RUNNING=0                           # DHCP client availability\n    ARPWATCH_RUNNING=0                              # ARP-cache based attack monitoring software\n    ARPON_RUNNING=0                                 # ARP-cache based attack monitoring software\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_NETWORKING}\"\n#\n#################################################################################\n#\n    # Test        : NETW-2400\n    # Description : Test hostname for valid characters and length\n    # Notes       : FQDN: max 253 characters\n    #             : component: a-z, 0-9, hyphen, not start with hyphen, max 63 characters\n    #               dots allowed as separator\n    Register --test-no NETW-2400 --weight L --network YES --category basics --description \"Hostname length and value check\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Test first the fully qualified domain name\n        if [ ${#FQDN} -gt 253 ]; then\n            # Too long\n            LogText \"Result: FQDN is more than 253 characters\"\n            Display --indent 2 --text \"- Hostname (FQDN length)\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Hostname is too long (more than 253 characters)\"\n        elif [ ${#FQDN} -eq 0 ]; then\n            # FQDN not defined\n            LogText \"Result: FQDN is not defined\"\n            if IsVerbose; then Display --indent 2 --text \"- Hostname (FQDN length)\" --result \"${STATUS_UNKNOWN}\" --color YELLOW; fi\n        else\n            # Fine\n            LogText \"Result: FQDN is defined and not longer than 253 characters (${#FQDN} characters)\"\n            if IsVerbose; then Display --indent 2 --text \"- Hostname (FQDN length)\" --result \"${STATUS_OK}\" --color GREEN; fi\n        fi\n        # Now test short hostname\n        if [ ${#HOSTNAME} -eq 0 ]; then\n            if IsVerbose; then Display --indent 2 --text \"- Hostname (FQDN length)\" --result \"${STATUS_NONE}\" --color RED; fi\n            LogText \"Result: hostname is not defined\"\n        else\n            # Test length\n            if [ ${#HOSTNAME} -gt 63 ]; then\n                LogText \"Result: hostname is more than 63 characters\"\n                Display --indent 2 --text \"- Hostname (length)\" --result \"${STATUS_WARNING}\" --color RED\n            else\n                LogText \"Result: hostnamed is defined and not longer than 63 characters\"\n            fi\n            # Test valid characters (normally a dot should not be in the name, but we can't be 100% sure we have short name)\n            FIND=$(echo \"${HOSTNAME}\" | ${TRBINARY} -d '[:alnum:]\\.\\-')\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: good, no unexpected characters discovered in hostname\"\n                if IsVerbose; then Display --indent 2 --text \"- Hostname (allowed characters)\" --result \"${STATUS_OK}\" --color GREEN; fi\n            else\n                LogText \"Result: unexpected characters discovered in hostname (characters: ${FIND}), which may impact network connectivity\"\n                Display --indent 2 --text \"- Hostname (allowed characters)\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"Hostname contains invalid characters\" \"hostname\" \"text:See log file for invalid characters\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-2600\n    # Description : Gather IPv6 configuration\n    Register --test-no NETW-2600 --os \"Linux\" --weight L --network YES --category security --description \"Checking IPv6 configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        IPV6_CONFIGURED=0\n        IPV6_ACCEPT_RA=255\n        IPV6_ACCEPT_REDIRECTS=255\n        IPV6_MANUAL_CONFIGURED=255\n        IPV6_ONLY=255\n        IPV6_MISCONFIGURED=0\n        IPV6_MISCONFIGURED_MTU=0\n        FIND=$(sysctl -a 2> /dev/null | ${GREPBINARY} \"^net.ipv6\" | ${SEDBINARY} \"s/ = /=/\")\n        if [ -n \"${FIND}\" ]; then\n            IPV6_CONFIGURED=1\n            for I in ${FIND}; do\n                SYSCTL_KEY=$(echo ${I} | ${AWKBINARY} -F= '{ print $1 }')\n                SYSCTL_VALUE=$(echo ${I} | ${AWKBINARY} -F= '{ print $2 }')\n                case ${SYSCTL_KEY} in\n                    \"net.ipv6.conf.default.accept_ra\")\n                        if [ \"${SYSCTL_VALUE}\" = \"1\" ]; then IPV6_ACCEPT_RA=1; else IPV6_ACCEPT_RA=0; fi\n                    ;;\n                    \"net.ipv6.conf.default.accept_redirects\")\n                        if [ \"${SYSCTL_VALUE}\" = \"1\" ]; then IPV6_ACCEPT_REDIRECTS=1; else IPV6_ACCEPT_REDIRECTS=0; fi\n                    ;;\n                    \"net.ipv6.bindv6only\")\n                        if [ \"${SYSCTL_VALUE}\" = \"1\" ]; then IPV6_ONLY=1; else IPV6_ONLY=0; fi\n                    ;;\n                    \"net.ipv6.conf.all.mtu\" | \"net.ipv6.conf.default.mtu\")\n                        if [ ${SYSCTL_VALUE} -lt 1280 ]; then IPV6_MISCONFIGURED_MTU=1; fi\n                    ;;\n\n                    #if TestValue --function equals --value \"${SYSCTL_VALUE}\" --search \"1\"; then\n                    #     echo \"Found ${SYSCTL_VALUE}\"\n                    #else\n                    #     echo \"Not found\"\n                    #fi\n                esac\n            done\n        else\n            IPV6_MODE=\"disabled\"\n        fi\n        # Check if we are manually configured (not accepting automatic configuration)\n        if [ ${IPV6_ACCEPT_RA} -eq 0 -a ${IPV6_ACCEPT_REDIRECTS} -eq 0 ]; then\n            IPV6_MANUAL_CONFIGURED=1\n            IPV6_MODE=\"manual\"\n        elif [ ${IPV6_ACCEPT_RA} -eq 1 -o ${IPV6_ACCEPT_REDIRECTS} -eq 1 ]; then\n            IPV6_MODE=\"auto\"\n        else\n            IPV6_MODE=\"disabled\"\n        fi\n\n        LogText \"Result: IPV6 mode is ${IPV6_MODE}\"\n        if [ ${IPV6_CONFIGURED} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking IPv6 configuration\" --result \"${STATUS_ENABLED}\" --color WHITE\n            STATUS=$(echo ${IPV6_MODE} | ${TRBINARY} '[:lower:]' '[:upper:]')\n            Display --indent 6 --text \"Configuration method\" --result \"${STATUS}\" --color WHITE\n            if [ ${IPV6_ONLY} -eq 1 ]; then STATUS=\"${STATUS_YES}\"; else STATUS=\"${STATUS_NO}\"; fi\n            LogText \"Result: IPv6 only configuration: ${STATUS}\"\n            Display --indent 6 --text \"IPv6 only\" --result \"${STATUS}\" --color WHITE\n        else\n            Display --indent 2 --text \"- Checking IPv6 configuration\" --result \"${STATUS_DISABLED}\" --color WHITE\n        fi\n        # Configuration errors\n        if [ ${IPV6_MISCONFIGURED_MTU} -eq 1 ]; then\n            IPV6_MISCONFIGURED=1\n            LogText \"Result: MTU of IPv6 interfaces should be 1280 or higher\"\n            Display --indent 6 --text \"Error: MTU is too low\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check your MTU configuration of IPv6 interfaces\"\n        fi\n\n        # Possible improvements:\n        # - Check if we found IPv6 enabled nameservers\n\n        # Report\n        Report \"ipv6_mode=${IPV6_MODE}\"\n        Report \"ipv6_only=${IPV6_ONLY}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-2704\n    # Description : Basic nameserver configuration tests (connectivity)\n    Register --test-no NETW-2704 --weight L --network YES --category security --description \"Basic nameserver configuration tests\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 2 --text \"- Checking configured nameservers\"\n        LogText \"Test: Checking /etc/resolv.conf file\"\n        if [ -f /etc/resolv.conf ]; then\n            LogText \"Result: Found /etc/resolv.conf file\"\n            FIND=$(${GREPBINARY} '^nameserver' /etc/resolv.conf | ${TRBINARY} -d '\\t' | ${SEDBINARY} 's/nameserver*//g' | uniq | ${CUTBINARY} -d# -f1)\n            if [ -n \"${FIND}\" ]; then\n                Display --indent 4 --text \"- Testing nameservers\"\n                LogText \"Test: Querying nameservers\"\n                for I in ${FIND}; do\n                    LogText \"Found nameserver: ${I}\"\n                    Report \"nameserver[]=${I}\"\n                    # Check if a local resolver is available (like DNSMasq)\n                    if [ \"${I}\" = \"::1\" -o \"${I}\" = \"127.0.0.1\" -o \"${I}\" = \"127.0.0.53\" -o \"${I}\" = \"127.0.1.1\" -o \"${I}\" = \"0.0.0.0\" ]; then\n                        LOCAL_DNSRESOLVER_FOUND=1\n                    fi\n                    if [ -n \"${DIGBINARY}\" ]; then\n                        # See if we can query something at the nameserver\n                        # 0=good, other=bad\n                        DNSRESPONSE=$(${DIGBINARY} +noall +time=3 +retry=0 @${I} ${FQDN} > /dev/null ; echo $?)\n                        if [ \"${DNSRESPONSE}\" = \"0\" ]; then\n                            Display --indent 8 --text \"Nameserver: ${I}\" --result \"${STATUS_OK}\" --color GREEN\n                            LogText \"Nameserver ${I} seems to respond to queries from this host.\"\n                            # Count responsive nameservers\n                            NUMBERACTIVENS=$((NUMBERACTIVENS + 1))\n                        else\n                            Display --indent 8 --text \"Nameserver: ${I}\" --result \"NO RESPONSE\" --color RED\n                            LogText \"Result: nameserver ${I} does NOT respond\"\n                            LogText \"Exit-code from dig: ${DNSRESPONSE}\"\n                            ReportSuggestion \"${TEST_NO}\" \"Check connection to this nameserver and make sure no outbound DNS queries are blocked (port 53 UDP and TCP).\"\n                            ReportWarning \"${TEST_NO}\" \"Nameserver ${I} does not respond\"\n                        fi\n                    else\n                        LogText \"Result: Nameserver test for ${I} skipped, 'dig' not installed\"\n                        Display --indent 6 --text \"Nameserver: ${I}\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n                    fi\n                done\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-2705\n    # Description : Basic nameserver configuration tests (connectivity)\n    if [ ${LOCAL_DNSRESOLVER_FOUND} -eq 0 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NETW-2705 --preqs-met ${PREQS_MET} --weight L --network YES --category security --description \"Check availability two nameservers\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        SKIP=0\n        if [ -n \"${DIGBINARY}\" ]; then\n            if [ ${NUMBERACTIVENS} -lt 2 ]; then\n                Display --indent 4 --text \"- Minimal of 2 responsive nameservers\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: less than 2 responsive nameservers found\"\n                ReportWarning \"${TEST_NO}\" \"Couldn't find 2 responsive nameservers\"\n                LogText \"Note: Non responsive nameservers can give problems for your system(s). Like the lack of recursive lookups, bad connectivity to update servers etc.\"\n                ReportSuggestion \"${TEST_NO}\" \"Check your resolv.conf file and fill in a backup nameserver if possible\"\n                AddHP 1 2\n            else\n                Display --indent 4 --text \"- Minimal of 2 responsive nameservers\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: found at least 2 responsive nameservers\"\n                AddHP 3 3\n            fi\n        else\n            Display --indent 4 --text \"- Minimal of 2 responsive nameservers\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n            LogText \"Result: dig not installed, test can't be fully performed\"\n        fi\n    else\n        LogText \"Result: Test most likely skipped due having local resolver in /etc/resolv.conf\"\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-2706\n    # Description : Check systemd-resolve output and upstream DNSSEC status\n    # Notes       : Ubuntu 16.04 uses systemd-resolve, newer ones most likely resolvectl\n    if [ -n \"${RESOLVECTLBINARY}\" ]; then\n        PREQS_MET=\"YES\"\n        RESOLVE_CMD=\"${RESOLVECTLBINARY}\"\n        RESOLVE_CMD_PARAM=\"statistics\"\n    elif [ -n \"$(command -v systemd-resolve 2> /dev/null)\" ]; then\n        PREQS_MET=\"YES\"\n        RESOLVE_CMD=\"$(command -v systemd-resolve 2> /dev/null)\"\n        RESOLVE_CMD_PARAM=\"--statistics\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n    Register --test-no NETW-2706 --preqs-met \"${PREQS_MET}\" --weight L --network YES --category security --description \"Check systemd-resolved and upstream DNSSEC status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        SKIP=0\n        DNSSEC_STATUS=$(${RESOLVE_CMD} ${RESOLVE_CMD_PARAM} 2> /dev/null | ${AWKBINARY} -F \":\" '/DNSSEC supported/ { print $2 }' | ${TRBINARY} -d ' ')\n        if [ \"${DNSSEC_STATUS}\" = \"yes\" ]; then\n            Display --indent 4 --text \"- DNSSEC supported (systemd-resolved)\" --result \"${STATUS_YES}\" --color GREEN\n            LogText \"Result: DNSSEC supported by systemd-resolved and upstream DNS servers\"\n        elif [ \"${DNSSEC_STATUS}\" = \"no\" ]; then\n            Display --indent 4 --text \"- DNSSEC supported (systemd-resolved)\" --result \"${STATUS_NO}\" --color YELLOW\n            LogText \"Result: DNSSEC not supported by systemd-resolved or upstream DNS servers\"\n        else\n            Display --indent 4 --text \"- DNSSEC supported (systemd-resolved)\" --result \"${STATUS_UNKNOWN}\" --color RED\n            LogText \"Result: command '${RESOLVE_CMD} ${RESOLVE_CMD_PARAM}' returned an error. Please run command manually to check for details.\"\n        fi\n    else\n        LogText \"Result: Test most likely skipped due to not having resolvectl\"\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3001\n    # Description : Find default gateway (route)\n    # More info   : BSD: ^default   Linux: 0.0.0.0\n    if [ -n \"${NETSTATBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NETW-3001 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Find default gateway (route)\"\n    if [ $SKIPTEST -eq 0 ]; then\n        LogText \"Test: Searching default gateway(s)\"\n        FIND=$(${NETSTATBINARY} -rn | ${GREPBINARY} -E \"^0.0.0.0|default\" | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f2)\n        if [ -n \"${FIND}\" ]; then\n            for I in ${FIND}; do\n                LogText \"Result: Found default gateway ${I}\"\n                Report \"default_gateway[]=${I}\"\n            done\n            Display --indent 2 --text \"- Checking default gateway\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            LogText \"Result: No default gateway found\"\n            Display --indent 2 --text \"- Checking default gateway\" --result \"NONE FOUND\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3004\n    # Description : Find available network interfaces\n    Register --test-no NETW-3004 --weight L --network NO --category security --description \"Search for available network interfaces\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=\"\"\n        case ${OS} in\n            AIX)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${GREPBINARY} \"flags=\" | ${AWKBINARY} -F \":\" '{ print  $1 }')\n            ;;\n            Linux)\n                if [ -n \"${IPBINARY}\" ]; then\n                    FIND=$(${IPBINARY} link show 2> /dev/null | ${GREPBINARY} \"^[0-9]\" | ${AWKBINARY} '{ print $2 }' | ${SEDBINARY} 's/://g')\n                elif [ -n \"${IFCONFIGBINARY}\" ]; then\n                    FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ( $2 == \"Link\" ) { print  $1 }}')\n                fi\n            ;;\n            DragonFly|FreeBSD|macOS|NetBSD)\n                FIND=$(${IFCONFIGBINARY} -l 2> /dev/null)\n            ;;\n            OpenBSD|Solaris)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${GREPBINARY} \"flags=\" | ${AWKBINARY} -F \": \" '{ print  $1 }')\n            ;;\n            *)\n                # Having a system currently unsupported? Share your details to determine network interfaces\n                ReportException \"${TEST_NO}:1\" \"No support for this OS (${OS}) to find available network interfaces\"\n            ;;\n        esac\n        if HasData \"${FIND}\"; then\n            for ITEM in ${FIND}; do\n                NETWORK_INTERFACES=\"${NETWORK_INTERFACES}|${ITEM}\"\n                LogText \"Found network interface: ${ITEM}\"\n                Report \"network_interface[]=${ITEM}\"\n            done\n        else\n            ReportException \"${TEST_NO}:1\" \"No interfaces found on this system (OS=${OS})\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3006\n    # Description : Get network MAC addresses\n    Register --test-no NETW-3006 --weight L --network NO --category security --description \"Get network MAC addresses\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=\"\"\n        case ${OS} in\n            AIX)\n                FIND=$(lscfg -vl ent* | ${GREPBINARY} \"Network Address\" | ${CUTBINARY} -d\".\" -f14 | ${AWKBINARY} '{ ctr=1; i=1; while (ctr <= 6) { d[ctr++]=substr($0,i,2);i=i+2 } printf(\"%s:%s:%s:%s:%s:%s\\n\",d[1],d[2],d[3],d[4],d[5],d[6]) }')\n                ;;\n            DragonFly|FreeBSD)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"ether\") print $2 }' | ${SORTBINARY} -u)\n                ;;\n            Linux)\n                if [ -n \"${IFCONFIGBINARY}\" ]; then\n                    FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${GREPBINARY} \"HWaddr\" | ${AWKBINARY} '{ if ($4==\"HWaddr\") print $5 }' | ${SORTBINARY} -u)\n                    # CentOS 7.x and others may return nothing. Let's retry with 'ether' field.\n                    if [ -z \"${FIND}\" ]; then\n                        FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"ether\") print $2 }' | ${SORTBINARY} -u)\n                    fi\n                else\n                    if [ -n \"${IPBINARY}\" ]; then\n                        LogText \"Test: Using ip binary to gather hardware addresses\"\n                        FIND=$(${IPBINARY} link 2> /dev/null | ${GREPBINARY} \"link/ether\" | ${AWKBINARY} '{ print $2 }')\n                    else\n                        ReportException \"${TEST_NO}:2\" \"Missing ifconfig or ip command to collect hardware address (MAC)\"\n                    fi\n                fi\n                ;;\n            macOS)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"lladdr\" || $1==\"ether\") print $2 }' | ${SORTBINARY} -u)\n                ;;\n            NetBSD)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"address:\") print $2 }' | ${SORTBINARY} -u)\n                ;;\n            OpenBSD)\n                FIND=$(${IFCONFIGBINARY} -A 2> /dev/null | ${AWKBINARY} '{ if ($1==\"lladdr\") print $2 }' | ${SORTBINARY} -u)\n                ;;\n            Solaris)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"ether\") print $2 }' | ${SORTBINARY} -u)\n                ;;\n            *)\n                # Having a system currently unsupported? Share your details to determine MAC information\n                ReportException \"${TEST_NO}:1\" \"No support for this OS (${OS}) to find MAC information\"\n                ;;\n        esac\n        for ITEM in ${FIND}; do\n            LogText \"Found MAC address: ${ITEM}\"\n            Report \"network_mac_address[]=${ITEM}\"\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3008\n    # Description : Get network IPv4/6 addresses\n    Register --test-no NETW-3008 --weight L --network NO --category security --description \"Get network IP addresses\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=\"\"; FIND2=\"\"\n        case ${OS} in\n            AIX)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") print $2 }')\n                FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\") print $2 }')\n                ;;\n            DragonFly|FreeBSD|NetBSD)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") print $2 }')\n                FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\") print $2 }')\n                ;;\n            Linux)\n                if [ -n \"${IFCONFIGBINARY}\" ]; then\n                    FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") print $2 }' | ${CUTBINARY} -d ':' -f2)\n                    # Version which works for multiple types of ifconfig (e.g. Slackware)\n                    FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\" && $2==\"addr:\") { print $3 } else { if ($1==\"inet6\" && $3==\"prefixlen\") { print $2 } } }')\n                else\n                    if [ -n \"${IPBINARY}\" ]; then\n                        LogText \"Test: Using ip binary to gather IP addresses\"\n                        FIND=$(${IPBINARY} addr 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") { print $2 }}' | ${SEDBINARY} 's/\\/.*//')\n                        FIND2=$(${IPBINARY} addr 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\") { print $2 }}' | ${SEDBINARY} 's/\\/.*//')\n                    else\n                        ReportException \"${TEST_NO}:2\" \"Missing ifconfig or ip command to collect hardware address (MAC)\"\n                    fi\n                fi\n                ;;\n            macOS)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") print $2 }')\n                FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\") print $2 }')\n                ;;\n            OpenBSD)\n                FIND=$(${IFCONFIGBINARY} -A 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") print $2 }')\n                FIND2=$(${IFCONFIGBINARY} -A 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\") print $2 }')\n                ;;\n            Solaris)\n                FIND=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet\") print $2 }')\n                FIND2=$(${IFCONFIGBINARY} -a 2> /dev/null | ${AWKBINARY} '{ if ($1==\"inet6\") print $2 }')\n                ;;\n            *)\n                LogText \"Result: no support yet for this OS (${OS}) to find IP address information. You can help improving this test by submitting your details.\"\n                ReportException \"${TEST_NO}:1\" \"IP address information test not implemented for this operating system\"\n                ;;\n        esac\n\n        # IPv4\n        for ITEM in ${FIND}; do\n            LogText \"Found IPv4 address: ${ITEM}\"\n            Report \"network_ipv4_address[]=${ITEM}\"\n        done\n        # IPv6\n        for ITEM in ${FIND2}; do\n            LogText \"Found IPv6 address: ${ITEM}\"\n            Report \"network_ipv6_address[]=${ITEM}\"\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3012\n    # Description : Check listening ports\n    Register --test-no NETW-3012 --weight L --network NO --category security --description \"Check listening ports\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        DATA=\"\"\n        FIND=\"\"; FIND2=\"\"\n        COUNT=0\n        case ${OS} in\n            DragonFly | FreeBSD)\n                if [ -n \"${SOCKSTATBINARY}\" ]; then\n                    FIND=$(${SOCKSTATBINARY} | ${AWKBINARY} '{ if ($7 ~ /\\*:\\*/) print $5\"|\"$6\"|\"$2\"|\" }' | ${SORTBINARY} -u)\n                    # To strip off IP's: ${SEDBINARY} 's/|.*:/|/'\n                else\n                    FIND=\"\"\n                fi\n                FIND2=\"\"\n            ;;\n            Linux)\n                if [ -n \"${SSBINARY}\" ]; then\n                    LogText \"Test: Retrieving ss information to find listening ports\"\n                    DATA=$(${SSBINARY} --query=udp,tcp -plnt | ${AWKBINARY} '{ if ($1!=\"Netid\") { print \"raw,ss,v1|\"$1\"|\"$5\"|\"$7\"|\" }}' | ${SEDBINARY} 's/pid=[0-9]\\{1,\\},fd=[0-9]\\{1,\\}//g' | ${SEDBINARY} 's/users://' | ${SEDBINARY} 's/,)//g' | ${TRBINARY} -d '()\"')\n                elif [ -n \"${NETSTATBINARY}\" ]; then\n                    LogText \"Test: Retrieving netstat information to find listening ports\"\n                    # UDP\n                    FIND=$(${NETSTATBINARY} -nlp 2> /dev/null | ${GREPBINARY} \"^udp\" | ${AWKBINARY} '{ print $4\"|\"$1\"|\"$6\"|\" }' | ${SEDBINARY} 's:|[0-9]*/:|:')\n                    # TCP\n                    FIND2=$(${NETSTATBINARY} -nlp 2> /dev/null  | ${GREPBINARY} \"^tcp\" | ${AWKBINARY} '{ if($6==\"LISTEN\") { print $4\"|\"$1\"|\"$7\"|\" }}' | ${SEDBINARY} 's:|[0-9]*/:|:')\n                else\n                    ReportException \"${TEST_NO}:1\" \"netstat and ss binary missing to gather listening ports\"\n                fi\n            ;;\n\n            macOS)\n                if [ -n \"${LSOFBINARY}\" ]; then\n                    LogText \"Test: Retrieving lsof information to find listening ports\"\n                    # UDP and TCP combined\n                    FIND=$(${LSOFBINARY}${LSOF_EXTRA_OPTIONS} -i -P | ${AWKBINARY} '{ print $9\"|\"$8\"|\"$1\"|\" }' | ${SEDBINARY} 's/\\(.*\\)\\-\\>.*\\(\\|.*\\)/\\1\\2/' | ${SEDBINARY} 's/\\*/'$IP'/' | ${SORTBINARY} -u | ${GREPBINARY} -v \"NAME\")\n                else\n                    FIND=\"\"\n                fi\n                # Not needed as we have a combined test\n                FIND2=\"\"\n            ;;\n            NetBSD)\n                if [ -n \"${SOCKSTATBINARY}\" ]; then\n                    LogText \"Test: Retrieving sockstat information to find listening ports\"\n                    FIND=$(${SOCKSTATBINARY} 2> /dev/null | ${AWKBINARY} '{ if ($7 ~ /\\*.\\*/) print $5\"|\"$6\"|\"$2\"|\" }' | ${SORTBINARY} -u)\n                else\n                    FIND=\"\"\n                fi\n                FIND2=\"\"\n            ;;\n            OpenBSD)\n                if [ -n \"${NETSTATBINARY}\" ]; then\n                    LogText \"Test: Retrieving netstat information to find listening ports\"\n                    # UDP\n                    FIND=$(${NETSTATBINARY} -an 2> /dev/null | ${GREPBINARY} \"^udp\" | ${AWKBINARY} '{ print $4\"|\"$1\"||\" }')\n                    # TCP\n                    FIND2=$(${NETSTATBINARY} -an 2> /dev/null  | ${GREPBINARY} \"^tcp\" | ${AWKBINARY} '{ if($6==\"LISTEN\") { print $4\"|\"$1\"||\" }}')\n                else\n                    ReportException \"${TEST_NO}:3\" \"netstat missing to gather listening ports\"\n                fi\n            ;;\n            Solaris)\n                if [ -n \"${NETSTATBINARY}\" ]; then\n                    LogText \"Test: Retrieving netstat information to find listening ports\"\n                    FIND=$(${NETSTATBINARY} -an -P udp | ${AWKBINARY} '{ if($7==\"LISTEN\") { print $1\"|udp|LISTEN|\" }}')\n                    FIND2=$(${NETSTATBINARY} -an -P tcp | ${AWKBINARY} '{ if($7==\"LISTEN\") { print $1\"|tcp|LISTEN|\" }}')\n                else\n                    ReportException \"${TEST_NO}:4\" \"netstat missing to gather listening ports\"\n                fi\n            ;;\n            *)\n                # Got this exception? Provide your details and output of netstat or any other tool to determine this information.\n                ReportException \"${TEST_NO}:2\" \"Unclear what method to use, to determine listening port information\"\n            ;;\n        esac\n\n        if [ -n \"${DATA}\" ]; then\n            for ITEM in ${DATA}; do\n                COUNT=$((COUNT + 1))\n                Report \"network_listen[]=${ITEM}\"\n            done\n        fi\n\n        if [ -n \"${FIND}\" ]; then\n            for ITEM in ${FIND}; do\n                COUNT=$((COUNT + 1))\n                LogText \"Found listening info: ${ITEM}\"\n                Report \"network_listen_port[]=${ITEM}\"\n            done\n        fi\n\n        if [ -n \"${FIND2}\" ]; then\n            for ITEM in ${FIND2}; do\n                COUNT=$((COUNT + 1))\n                LogText \"Found listening info: ${ITEM}\"\n                Report \"network_listen_port[]=${ITEM}\"\n            done\n        fi\n        if [ -z \"${DATA}\" -a -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Getting listening ports (TCP/UDP)\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n        else\n            Display --indent 2 --text \"- Getting listening ports (TCP/UDP)\" --result \"${STATUS_DONE}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3014\n    # Description : Checking promiscuous interfaces (BSD)\n    # Note        : FreeBSD and others\n    if [ \"${OS}\" = \"DragonFly\" -o \"${OS}\" = \"FreeBSD\" -o \"${OS}\" = \"NetBSD\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NETW-3014 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking promiscuous interfaces (BSD)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking promiscuous interfaces (FreeBSD)\"\n        FIND=$(${IFCONFIGBINARY} 2> /dev/null | ${GREPBINARY} PROMISC | ${CUTBINARY} -d ':' -f1)\n        if HasData \"${FIND}\"; then\n            LogText \"Result: Promiscuous interfaces: ${FIND}\"\n            for ITEM in ${FIND}; do\n                WHITELISTED=0\n                for PROFILE in ${PROFILES}; do\n                    Debug \"Checking if interface ${ITEM} is whitelisted in profile ${PROFILE}\"\n                    ISWHITELISTED=$(${GREPBINARY} \"^if_promisc:${ITEM}:\" ${PROFILE})\n                    if HasData \"${ISWHITELISTED}\"; then\n                        WHITELISTED=1\n                        LogText \"Result: this interface was whitelisted in profile (${PROFILE})\"\n                    fi\n                done\n                # Check if this interface was whitelisted\n                if [ ${WHITELISTED} -eq 0 ]; then\n                    FOUNDPROMISC=1\n                    ReportWarning \"${TEST_NO}\" \"Found promiscuous interface (${ITEM})\"\n                    LogText \"Note: some tools put an interface into promiscuous mode, to capture/log network traffic\"\n                else\n                    LogText \"Result: Found promiscuous interface ${ITEM} (*whitelisted via profile*)\"\n                fi\n            done\n        fi\n\n        # Show result\n        if [ ${FOUNDPROMISC} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking promiscuous interfaces\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: No promiscuous interfaces found\"\n        else\n            Display --indent 2 --text \"- Checking promiscuous interfaces\" --result \"${STATUS_WARNING}\" --color RED\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3015\n    # Description : Checking promiscuous interfaces (Linux)\n    Register --test-no NETW-3015 --os Linux --weight L --network NO --category security --description \"Checking promiscuous interfaces (Linux)\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUNDPROMISC=99\n        NETWORK=\"\"\n        USE_IP_INSTEAD_IFCONFIG=0\n\n        if [ -n \"${IPBINARY}\" ]; then\n            LogText \"Test: Using ip binary to retrieve network interfaces\"\n            NETWORK=$(${IPBINARY} -o link 2> /dev/null | ${GREPBINARY} \"^[0-9]\" | ${AWKBINARY} '{print $2 }' | ${TRBINARY} -d ':')\n            USE_IP_INSTEAD_IFCONFIG=1\n        elif [ -n \"${IFCONFIGBINARY}\" ]; then\n            LogText \"Test: Using ifconfig binary to retrieve network interfaces\"\n            NETWORK=$(${IFCONFIGBINARY} 2> /dev/null | ${GREPBINARY} Link | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f1)\n        fi\n\n        LogText \"Test: Checking all interfaces to discover any with promiscuous mode enabled\"\n        if [ -n \"${NETWORK}\" ]; then\n            FOUNDPROMISC=0\n            for I in ${NETWORK}; do\n                if [ ${USE_IP_INSTEAD_IFCONFIG} -eq 1 ]; then\n                    FIND=$(${IPBINARY} -o -d link show ${I} 2> /dev/null | ${GREPBINARY} \"promiscuity [1-9]\")\n                else\n                    FIND=$(${IFCONFIGBINARY} ${I} 2> /dev/null | ${GREPBINARY} PROMISC)\n                fi\n                if [ -n \"${FIND}\" ]; then\n                    LogText \"Result: Promiscuous interface: ${I}\"\n                    ISWHITELISTED=$(${GREPBINARY} \"^if_promisc:${I}:\" ${PROFILE})\n                    if [ -z \"${ISWHITELISTED}\" ]; then\n                        FOUNDPROMISC=1\n                        ReportWarning \"${TEST_NO}\" \"Found promiscuous interface\" \"${I}\" \"text:Determine if this mode is required or whitelist interface in profile\"\n                        LogText \"Note: some tools put an interface into promiscuous mode, to capture/log network traffic\"\n                    else\n                        LogText \"Result: Found promiscuous interface ${I} (*whitelisted via profile*)\"\n                    fi\n                fi\n            done\n        else\n            LogText \"Result: no network interfaces discovered, so nothing tested\"\n        fi\n\n        # Show result\n        if [ ${FOUNDPROMISC} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking promiscuous interfaces\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: No promiscuous interfaces found\"\n        elif [ ${FOUNDPROMISC} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking promiscuous interfaces\" --result \"${STATUS_WARNING}\" --color RED\n        else\n            Display --indent 2 --text \"- Checking promiscuous interfaces\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Do you have a multipath configuration on Linux or other OS? Create a related test and send in a pull request on GitHub\n\n    # Test        : NETW-3020 TODO\n    # Description : Checking multipath configuration\n#\n#################################################################################\n#\n    # Test        : NETW-3028\n    # Description : Checking for many waiting connections\n    # Type        : Performance\n    # Notes       : It is common to see a healthy web server seeing to have several thousands of TCP connections in WAIT state\n    if [ ! \"${NETSTATBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no NETW-3028 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking connections in WAIT state\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Using netstat for check for connections in WAIT state\"\n        FIND=$(${NETSTATBINARY} -an | ${GREPBINARY} WAIT | ${WCBINARY} -l | ${AWKBINARY} '{ print $1 }')\n        if IsEmpty \"${OPTIONS_CONN_MAX_WAIT_STATE}\"; then OPTIONS_CONN_MAX_WAIT_STATE=\"5000\"; fi\n        LogText \"Result: currently ${FIND} connections are in a waiting state (max configured: ${OPTIONS_CONN_MAX_WAIT_STATE}).\"\n        if [ ${FIND} -gt ${OPTIONS_CONN_MAX_WAIT_STATE} ]; then\n            Display --indent 2 --text \"- Checking waiting connections\" --result \"${STATUS_WARNING}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Determine why system has many connections in WAIT state (${FIND})\"\n        else\n            Display --indent 2 --text \"- Checking waiting connections\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: ${FIND} connections are in WAIT state\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3030\n    # Description : Checking for DHCP client\n    Register --test-no NETW-3030 --weight L --network NO --category security --description \"Checking DHCP client status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if IsRunning \"dhclient\" || IsRunning \"dhcpcd\" || IsRunning \"udhcpc\"; then\n            Display --indent 2 --text \"- Checking status DHCP client\" --result \"${STATUS_RUNNING}\" --color WHITE\n            DHCP_CLIENT_RUNNING=1\n        else\n            Display --indent 2 --text \"- Checking status DHCP client\" --result \"${STATUS_NOT_ACTIVE}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3032\n    # Description : Checking for ARP spoofing and related monitoring software\n    Register --test-no NETW-3032 --os Linux --weight L --network NO --category security --description \"Checking for ARP monitoring software\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n\n        # addrwatch\n        if IsRunning \"addrwatch\"; then\n            FOUND=1\n        fi\n\n        # arpwatch\n        if IsRunning \"arpwatch\"; then\n            FOUND=1\n            ARPWATCH_RUNNING=1\n        fi\n\n        # arpon\n        if IsRunning \"arpon\"; then\n            FOUND=1\n            ARPON_RUNNING=1\n        fi\n\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking for ARP monitoring software\" --result \"${STATUS_RUNNING}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Checking for ARP monitoring software\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            #ReportSuggestion \"${TEST_NO}\" \"Consider running ARP monitoring software (addrwatch,arpwatch,arpon)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : NETW-3200\n    # Description : Determine available network protocols\n    # Notes       : See all available supported modules: ls -d /lib/modules/$(uname -r )/kernel/net\n    #               To see active/enabled protocols: ls -d /proc/sys/net\n    Register --test-no NETW-3200 --weight L --network YES --category security --description \"Determine available network protocols\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        TESTED=0\n        FOUND_UNCOMMON_PROTOCOL_ENABLED=0\n        case ${OS} in\n            Linux)\n                TESTED=1\n                LogText \"Test: checking the status of some network protocols that typically are not used\"\n                UNCOMMON_PROTOCOLS=\"dccp sctp rds tipc\"\n                for P in ${UNCOMMON_PROTOCOLS}; do\n                    LogText \"Test: now checking module '${P}'\"\n                    if ! SkipAtomicTest \"${TEST_NO}:${P}\"; then\n                        UNCOMMON_PROTOCOL_DISABLED=0\n                        # First check modprobe.conf\n                        if [ -f ${ROOTDIR}etc/modprobe.conf ]; then\n                            DATA=$(${GREPBINARY} -E \"^install[[:space:]]+${P}[[:space:]]+/bin/(true|false)$\" ${ROOTDIR}etc/modprobe.conf)\n                            if [ -n \"${DATA}\" ]; then\n                                LogText \"Result: found ${P} module disabled via modprobe.conf\"\n                                UNCOMMON_PROTOCOL_DISABLED=1\n                            fi\n                        fi\n                        # Then additional modprobe configuration files\n                        if [ -d ${ROOTDIR}etc/modprobe.d ]; then\n                            # Return file names (-l) and suppress errors (-s)\n                            DATA=$(${GREPBINARY} -l -s -E \"^install[[:space:]]+${P}[[:space:]]+/bin/(true|false)$\" ${ROOTDIR}etc/modprobe.d/*)\n                            if [ -n \"${DATA}\" ]; then\n                                UNCOMMON_PROTOCOL_DISABLED=1\n                                for F in ${DATA}; do\n                                    LogText \"Result: found ${P} module disabled via ${F}\"\n                                done\n                            fi\n                        fi\n\n                        if [ ${UNCOMMON_PROTOCOL_DISABLED} -eq 0 ]; then\n                            ReportSuggestion \"${TEST_NO}\" \"Determine if protocol '${P}' is really needed on this system\"\n                            Report \"uncommon_network_protocol_enabled=${P}\"\n                            FOUND_UNCOMMON_PROTOCOL_ENABLED=1\n                        fi\n                    fi\n                done\n\n            ;;\n            *)\n                LogText \"This test has no routine yet for this operating system.\"\n                Debug \"No routine implemented yet for this operating system to check for available network protocols\"\n            ;;\n        esac\n        if [ ${TESTED} -eq 1 ]; then\n            if [ ${FOUND_UNCOMMON_PROTOCOL_ENABLED} -eq 1 ]; then\n                Display --indent 2 --text \"- Uncommon network protocols\" --result \"${FOUND}\" --color YELLOW\n            else\n                Display --indent 2 --text \"- Uncommon network protocols\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n            fi\n        fi\n        unset DATA F FOUND TESTED UNCOMMON_PROTOCOLS\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_php",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Software: PHP\n#\n#################################################################################\n#\n    # Variables\n    PHPVERSION=\"\"\n\n    InsertSection \"PHP\"\n\n    # Possible locations of php.ini\n    PHPINILOCS=\"${ROOTDIR}etc/php.ini ${ROOTDIR}etc/php.ini.default \\\n                ${ROOTDIR}etc/php/php.ini \\\n                ${ROOTDIR}etc/php7.0/php.ini \\\n                ${ROOTDIR}etc/php7.1/php.ini \\\n                ${ROOTDIR}etc/php7.2/php.ini \\\n                ${ROOTDIR}etc/php7.3/php.ini \\\n                ${ROOTDIR}etc/php7.4/php.ini \\\n                ${ROOTDIR}etc/php8.0/php.ini \\\n                ${ROOTDIR}etc/php8.1/php.ini \\\n                ${ROOTDIR}etc/php8.2/php.ini \\\n                ${ROOTDIR}etc/php8.3/php.ini \\\n                ${ROOTDIR}etc/php8.4/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php7.0/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php7.1/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php7.2/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php7.3/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php7.4/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php8.0/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php8.1/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php8.2/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php8.3/php.ini \\\n                ${ROOTDIR}etc/php/apache2-php8.4/php.ini \\\n                ${ROOTDIR}etc/php/cgi-php7.0/php.ini \\\n                ${ROOTDIR}etc/php/cgi-php7.1/php.ini \\\n                ${ROOTDIR}etc/php/cgi-php7.2/php.ini \\\n                ${ROOTDIR}etc/php/cgi-php7.3/php.ini \\\n                ${ROOTDIR}etc/php/cgi-php7.4/php.ini \\\n                ${ROOTDIR}etc/php/cli-php5.5/php.ini \\\n                ${ROOTDIR}etc/php/cli-php5.6/php.ini \\\n                ${ROOTDIR}etc/php/cli-php7.0/php.ini \\\n                ${ROOTDIR}etc/php/cli-php7.1/php.ini \\\n                ${ROOTDIR}etc/php/cli-php7.2/php.ini \\\n                ${ROOTDIR}etc/php/cli-php7.3/php.ini \\\n                ${ROOTDIR}etc/php/cli-php7.4/php.ini \\\n                ${ROOTDIR}etc/php/cli-php8.0/php.ini \\\n                ${ROOTDIR}etc/php/cli-php8.1/php.ini \\\n                ${ROOTDIR}etc/php/cli-php8.2/php.ini \\\n                ${ROOTDIR}etc/php/cli-php8.3/php.ini \\\n                ${ROOTDIR}etc/php/cli-php8.4/php.ini \\\n                ${ROOTDIR}etc/php/embed-php7.0/php.ini \\\n                ${ROOTDIR}etc/php/embed-php7.1/php.ini \\\n                ${ROOTDIR}etc/php/embed-php7.2/php.ini \\\n                ${ROOTDIR}etc/php/embed-php7.3/php.ini \\\n                ${ROOTDIR}etc/php/embed-php7.4/php.ini \\\n                ${ROOTDIR}etc/php/embed-php8.0/php.ini \\\n                ${ROOTDIR}etc/php/embed-php8.1/php.ini \\\n                ${ROOTDIR}etc/php/embed-php8.2/php.ini \\\n                ${ROOTDIR}etc/php/embed-php8.3/php.ini \\\n                ${ROOTDIR}etc/php/embed-php8.4/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php7.0/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php7.1/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php7.2/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php7.3/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php7.4/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php8.0/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php8.1/php.ini \\\n                ${ROOTDIR}etc/php/fpm-php8.2/php.ini \\\n                ${ROOTDIR}etc/php/7.0/apache2/php.ini \\\n                ${ROOTDIR}etc/php/7.1/apache2/php.ini \\\n                ${ROOTDIR}etc/php/7.2/apache2/php.ini \\\n                ${ROOTDIR}etc/php/7.3/apache2/php.ini \\\n                ${ROOTDIR}etc/php/7.4/apache2/php.ini \\\n                ${ROOTDIR}etc/php/8.0/apache2/php.ini \\\n                ${ROOTDIR}etc/php/8.1/apache2/php.ini \\\n                ${ROOTDIR}etc/php/8.2/apache2/php.ini \\\n                ${ROOTDIR}etc/php/8.3/apache2/php.ini \\\n                ${ROOTDIR}etc/php/8.4/apache2/php.ini \\\n                ${ROOTDIR}etc/php/7.0/cli/php.ini \\\n                ${ROOTDIR}etc/php/7.0/fpm/php.ini \\\n                ${ROOTDIR}etc/php/7.1/cli/php.ini \\\n                ${ROOTDIR}etc/php/7.1/fpm/php.ini \\\n                ${ROOTDIR}etc/php/7.2/cli/php.ini \\\n                ${ROOTDIR}etc/php/7.2/fpm/php.ini \\\n                ${ROOTDIR}etc/php/7.3/cli/php.ini \\\n                ${ROOTDIR}etc/php/7.3/fpm/php.ini \\\n                ${ROOTDIR}etc/php/7.4/cli/php.ini \\\n                ${ROOTDIR}etc/php/7.4/fpm/php.ini \\\n                ${ROOTDIR}etc/php/8.0/cli/php.ini \\\n                ${ROOTDIR}etc/php/8.0/fpm/php.ini \\\n                ${ROOTDIR}etc/php/8.1/cli/php.ini \\\n                ${ROOTDIR}etc/php/8.1/fpm/php.ini \\\n                ${ROOTDIR}etc/php/8.2/cli/php.ini \\\n                ${ROOTDIR}etc/php/8.2/fpm/php.ini \\\n                ${ROOTDIR}etc/php/8.3/cli/php.ini \\\n                ${ROOTDIR}etc/php/8.3/fpm/php.ini \\\n                ${ROOTDIR}etc/php/8.4/cli/php.ini \\\n                ${ROOTDIR}etc/php/8.4/fpm/php.ini \\\n                ${ROOTDIR}opt/alt/php70/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php71/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php72/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php73/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php74/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php80/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php81/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php82/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php83/etc/php.ini \\\n                ${ROOTDIR}opt/alt/php84/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php70/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php71/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php72/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php73/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php74/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php80/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php81/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php82/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php83/root/etc/php.ini \\\n                ${ROOTDIR}opt/cpanel/ea-php84/root/etc/php.ini \\\n                ${ROOTDIR}private/etc/php.ini \\\n                ${ROOTDIR}var/www/conf/php.ini \\\n                ${ROOTDIR}usr/local/etc/php.ini \\\n                ${ROOTDIR}usr/local/lib/php.ini \\\n                ${ROOTDIR}usr/local/php70/lib/php.ini \\\n                ${ROOTDIR}usr/local/php71/lib/php.ini \\\n                ${ROOTDIR}usr/local/php72/lib/php.ini \\\n                ${ROOTDIR}usr/local/php73/lib/php.ini \\\n                ${ROOTDIR}usr/local/php74/lib/php.ini \\\n                ${ROOTDIR}usr/local/php80/lib/php.ini \\\n                ${ROOTDIR}usr/local/php81/lib/php.ini \\\n                ${ROOTDIR}usr/local/php82/lib/php.ini \\\n                ${ROOTDIR}usr/local/php83/lib/php.ini \\\n                ${ROOTDIR}usr/local/php84/lib/php.ini \\\n                ${ROOTDIR}usr/local/zend/etc/php.ini \\\n                ${ROOTDIR}usr/pkg/etc/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php56/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php70/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php71/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php72/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php73/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php74/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php80/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php81/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php82/php.ini\\\n                ${ROOTDIR}etc/opt/remi/php83/php.ini \\\n                ${ROOTDIR}etc/opt/remi/php84/php.ini\"\n\n    PHPINIDIRS=\"${ROOTDIR}etc/php/7.0/cli/conf.d \\\n                ${ROOTDIR}etc/php/7.1/cli/conf.d \\\n                ${ROOTDIR}etc/php/7.2/cli/conf.d \\\n                ${ROOTDIR}etc/php/7.3/cli/conf.d \\\n                ${ROOTDIR}etc/php/7.4/cli/conf.d \\\n                ${ROOTDIR}etc/php/7.0/fpm/conf.d \\\n                ${ROOTDIR}etc/php/7.1/fpm/conf.d \\\n                ${ROOTDIR}etc/php/7.2/fpm/conf.d \\\n                ${ROOTDIR}etc/php/7.3/fpm/conf.d \\\n                ${ROOTDIR}etc/php/7.4/fpm/conf.d \\\n                ${ROOTDIR}etc/php/8.0/fpm/conf.d \\\n                ${ROOTDIR}etc/php/8.1/fpm/conf.d \\\n                ${ROOTDIR}etc/php/8.2/fpm/conf.d \\\n                ${ROOTDIR}etc/php/8.3/fpm/conf.d \\\n                ${ROOTDIR}etc/php/8.4/fpm/conf.d \\\n                ${ROOTDIR}etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php70/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php71/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php72/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php73/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php74/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php80/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php81/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php82/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php83/root/etc/php.d \\\n                ${ROOTDIR}opt/cpanel/ea-php84/root/etc/php.d \\\n                ${ROOTDIR}opt/alt/php70/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php71/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php72/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php73/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php74/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php80/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php81/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php82/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php83/etc/php.d.all \\\n                ${ROOTDIR}opt/alt/php84/etc/php.d.all \\\n                ${ROOTDIR}usr/local/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php70/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php71/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php72/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php73/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php74/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php80/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php81/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php82/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php83/lib/php.conf.d \\\n                ${ROOTDIR}usr/local/php84/lib/php.conf.d\"\n                \n    PHPINIDIRS=\"${PHPINIDIRS} \\\n                ${ROOTDIR}etc/php-7.0 \\\n                ${ROOTDIR}etc/php-7.1 \\\n                ${ROOTDIR}etc/php-7.2 \\\n                ${ROOTDIR}etc/php-7.3 \\\n                ${ROOTDIR}etc/php-7.4 \\\n                ${ROOTDIR}etc/php-8.0 \\\n                ${ROOTDIR}etc/php-8.1 \\\n                ${ROOTDIR}etc/php-8.2 \\\n                ${ROOTDIR}etc/php-8.3 \\\n                ${ROOTDIR}etc/php-8.4\"\n#\n#################################################################################\n#\n    # Test        : PHP-2211\n    # Description : Check php.ini presence\n    Register --test-no PHP-2211 --weight L --network NO --category security --description \"Check php.ini presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for presence php.ini\"\n        PHPINIFILE=\"\"\n        PHPINI_ALLFILES=\"\"\n        for FILE in ${PHPINILOCS}; do\n            LogText \"Test: checking presence ${FILE}\"\n            if [ -f ${FILE} ]; then\n                PHPINIFILE=\"${FILE}\"\n                LogText \"Result: Found php.ini file (${PHPINIFILE})\"\n                LogText \"Note: Adding file to php.ini array\"\n                PHPINI_ALLFILES=\"${PHPINI_ALLFILES} ${PHPINIFILE}\"\n            else\n                LogText \"Result: file ${FILE} not found\"\n            fi\n        done\n\n        # Check all known locations\n        for DIR in ${PHPINIDIRS}; do\n            FIND=$(ls ${DIR}/*.ini 2> /dev/null)\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: no files found for ${DIR}\"\n            else\n                LogText \"Result: found files in location ${DIR}, checking\"\n                for FILE in ${FIND}; do\n                    if [ -f ${FILE} ]; then\n                        LogText \"Result: file ${FILE} exists, adding to php.ini array\"\n                        PHPINI_ALLFILES=\"${PHPINI_ALLFILES} ${FILE}\"\n                    fi\n                done\n            fi\n        done\n\n        if [ -n \"${PHPINIFILE}\" ]; then\n            Display --indent 2 --text \"- Checking PHP\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: using single file ${PHPINIFILE} for main php.ini tests\"\n            LogText \"Result: using php.ini array ${PHPINI_ALLFILES} for further tests\"\n        else\n            Display --indent 2 --text \"- Checking PHP\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: no php.ini file found\"\n        fi\n        unset DIR FILE FIND\n    fi\n#\n#################################################################################\n#\n    # Test        : PHP-2320\n    # Description : Check php disable functions option\n    if [ -n \"${PHPINI_ALLFILES}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PHP-2320 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP disabled functions\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for I in ${PHPINI_ALLFILES}; do\n            LogText \"Test: Checking for PHP function hardening disabled_functions or suhosin.executor.func.blacklist in file ${I}\"\n            FIND=$(${GREPBINARY} \"^disable_functions.*=\" ${I})\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: ${I}: disabled_functions not found\"\n            else\n                LogText \"Result: ${I}: found disabled_functions\"\n                FOUND=1\n            fi\n\n            FIND=$(${GREPBINARY} \"^suhosin.executor.func.blacklist=\" ${I})\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: ${I}: suhosin.executor.func.blacklist not found\"\n            else\n                LogText \"Result: ${I}: found suhosin.executor.func.blacklist\"\n                FOUND=1\n            fi\n        done\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: all PHP functions can be executed\"\n            Display --indent 4 --text \"- Checking PHP disabled functions\" --result \"${STATUS_NONE}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Harden PHP by disabling risky functions\"\n            LogText \"Functions of interest to research/disable: chown, diskfreespace, disk_free_space, disk_total_space, dl, exec, escapeshellarg, escapeshellcmd, fileinode, highlight_file, max_execution_time, passthru, pclose, phpinfo, popen, proc_close, proc_open, proc_get_status, proc_nice, proc_open, proc_terminate, set_time_limit, shell_exec, show_source, system)\"\n            AddHP 0 1\n        else\n            LogText \"Result: one or more PHP functions are disabled/blacklisted\"\n            Display --indent 4 --text \"- Checking PHP disabled functions\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PHP-2368\n    # Description : Check php register_globals option\n    # Notes       : Don't test for it if PHP version is 5.4.0 or later (it has been removed)\n    if [ -n \"${PHPINIFILE}\" -a -n \"${PHPVERSION}\" -a -n \"${GREPBINARY}\" ]; then\n        if [ -f \"${PHPINIFILE}\" ]; then\n            FIND=$(echo ${PHPVERSION} | ${GREPBINARY} -E \"^(4.|5.[0-3])\")\n            if [ -z \"${FIND}\" ]; then\n                PREQS_MET=\"NO\"; Debug \"Found most likely PHP version 5.4.0 or higher (${PHPVERSION}) which does not use register_globals\"\n            else\n                PREQS_MET=\"YES\"; Debug \"Found PHP version 4 or up to 5.3 (${FIND}) which we are going to scan\"\n            fi\n        else\n            Debug \"File php.ini (${PHPINIFILE}) not found\"\n        fi\n    else\n        PREQS_MET=\"NO\"\n        Debug \"Skipping test: php.ini not found, or PHP version empty\"\n        Debug \"php.ini: ${PHPINIFILE}\"\n        Debug \"version: ${PHPVERSION}\"\n    fi\n    Register --test-no PHP-2368 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP register_globals option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking PHP register_globals option\"\n        FIND=$(${GREPBINARY} -E -i 'register_globals.*(on|yes|1)' ${PHPINIFILE} | ${GREPBINARY} -v '^;')\n        if [ -n \"${FIND}\" ]; then\n            Display --indent 4 --text \"- Checking register_globals option\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"PHP option register_globals option is turned on, which can be a risk for variable value overwriting\"\n            ReportSuggestion \"${TEST_NO}\" \"Change the register_globals line to: register_globals = Off\"\n            LogText \"Result: register_globals option is turned on, which can be a risk for variable value overwriting.\"\n            AddHP 1 2\n        else\n            Display --indent 4 --text \"- Checking register_globals option\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: No 'register_globals' found. Most likely it is in disabled state (0, no, or off), which is the default nowadays and considered the safe value.\"\n            ReportManual ${TEST_NO}:01\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PHP-2372\n    # Description : Check PHP expose_php option\n    # Background  : When this option is turned on, PHP will show its version number in the HTTP headers\n    # Notes       : TODO - Extend test to check all PHP files\n    if [ -n \"${PHPINI_ALLFILES}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PHP-2372 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP expose_php option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for FILE in ${PHPINI_ALLFILES}; do\n            # Don't look at this setting in cli configuration\n            case \"${FILE}\" in\n                */cli/*)\n                    continue\n                    ;;\n            esac\n            LogText \"Test: Checking file ${FILE}\"\n            FIND=$(${GREPBINARY} -E -i 'expose_php.*(on|yes|1)' ${FILE} | ${GREPBINARY} -v '^;')\n            if HasData \"${FIND}\"; then\n                LogText \"Result: found a a possible match on expose_php setting\"\n                LogText \"Data: ${FIND}\"\n                FOUND=1\n            fi\n        done\n\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 4 --text \"- Checking expose_php option\" --result \"${STATUS_ON}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Turn off PHP information exposure\" \"expose_php = Off\" \"-\"\n            Report \"Result: expose_php option is turned on, which can expose useful information for an attacker\"\n            AddHP 1 3\n        else\n            Display --indent 4 --text \"- Checking expose_php option\" --result \"${STATUS_OFF}\" --color GREEN\n            LogText \"Result: Found 'expose_php' in disabled state (0, no, or off)\"\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PHP-2374\n    # Description : Check PHP enable_dl option\n    # Notes       : Extend test to check all PHP files\n    if [ -n \"${PHPINIFILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PHP-2374 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP enable_dl option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking PHP enable_dl option\"\n        FIND=$(${GREPBINARY} -E -i 'enable_dl.*(on|yes|1)' ${PHPINIFILE} | ${GREPBINARY} -v '^;')\n        if [ -n \"${FIND}\" ]; then\n            Display --indent 4 --text \"- Checking enable_dl option\" --result \"${STATUS_ON}\" --color YELLOW\n            Report \"Result: enable_dl option is turned on, which can be used to enable more modules dynamically and circumventing security controls\"\n            ReportSuggestion \"${TEST_NO}\" \"Change the enable_dl line to: enable_dl = Off, to disable dynamically loading new modules\"\n            AddHP 0 1\n        else\n            Display --indent 4 --text \"- Checking enable_dl option\" --result \"${STATUS_OFF}\" --color GREEN\n            LogText \"Result: Found 'enable_dl' in disabled state (not present, 0, no, or off)\"\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PHP-2376\n    # Description : Check PHP allow_url_fopen option\n    # Notes       : Extend test to check all PHP files YYY\n    if [ -n \"${PHPINIFILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PHP-2376 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP allow_url_fopen option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking PHP allow_url_fopen option\"\n        FIND=$(${GREPBINARY} -E -i 'allow_url_fopen.*(off|no|0)' ${PHPINIFILE} | ${GREPBINARY} -v '^;')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 4 --text \"- Checking allow_url_fopen option\" --result \"${STATUS_ON}\" --color YELLOW\n            LogText \"Result: allow_url_fopen option is turned on, which can be used for downloads via PHP and is a security risk\"\n            ReportSuggestion \"${TEST_NO}\" \"Change the allow_url_fopen line to: allow_url_fopen = Off, to disable downloads via PHP\"\n            AddHP 0 1\n        else\n            Display --indent 4 --text \"- Checking allow_url_fopen option\" --result \"${STATUS_OFF}\" --color GREEN\n            LogText \"Result: Found 'allow_url_fopen' in disabled state (0, no, or off)\"\n            AddHP 2 2\n        fi\n        # TODO Check through all files\n    fi\n#\n#################################################################################\n#\n    # Test        : PHP-2378\n    # Description : Check PHP allow_url_include option\n    # Notes       : Extend test to check all PHP files YYY\n    if [ -n \"${PHPINIFILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PHP-2378 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP allow_url_include option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking PHP allow_url_include option\"\n        FIND=$(${GREPBINARY} -E -i 'allow_url_include.*(off|no|0)' ${PHPINIFILE} | ${GREPBINARY} -v '^;')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 4 --text \"- Checking allow_url_include option\" --result \"${STATUS_ON}\" --color YELLOW\n            Report \"Result: allow_url_include option is turned on, which can be used for downloads via PHP and is a risk\"\n            ReportSuggestion \"${TEST_NO}\" \"Change the allow_url_include line to: allow_url_include = Off, to disable downloads via PHP\"\n            AddHP 0 1\n        else\n            Display --indent 4 --text \"- Checking allow_url_include option\" --result \"${STATUS_OFF}\" --color GREEN\n            LogText \"Result: Found 'allow_url_include' in disabled state (0, no, or off)\"\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    # - test disabled for time being, as newer suhosin7 work is not stable enough -\n    # Test        : PHP-2379\n    # Description : Check PHP suhosin extension status\n    #if [ -n \"${PHPINI_ALLFILES}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    #Register --test-no PHP-2379 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP suhosin extension status\"\n\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    #    FOUND=0\n    #    SIMULATION=0\n    #    MAJOR_VERSION=$(echo ${PHPVERSION} | ${GREPBINARY} -E \"^7\")\n    #    if [ \"${OS}\" = \"OpenBSD\" ]; then\n    #        FOUND=1                    # On OpenBSD, Suhosin is hard linked into PHP\n    #        SIMULATION=off\n    #    else\n    #        for I in ${PHPINI_ALLFILES}; do\n    #            LogText \"Test: Checking for PHP suhosin extension status in file ${I}\"\n    #            FIND=$(${GREPBINARY} -oP '^extension=.*?suhosin7?.so.*$' ${I})\n    #            if [ -z \"${FIND}\" ]; then\n    #                LogText \"Result: ${I}: suhosin is not enabled\"\n    #            else\n    #                LogText \"Result: ${I}: suhosin is enabled\"\n    #                FOUND=1\n    #            fi\n\n    #            LogText \"Test: Check Suhosin simulation mode status\"\n    #            SIMULATION=$(${GREPBINARY} -oP '^suhosin.simulation.*$' ${I} | ${CUTBINARY} -d= -f2 | ${GREPBINARY} -io 'off' | ${TRBINARY} '[:upper:]' '[:lower:]')\n    #            if [ \"${SIMULATION}\" = \"off\" ]; then\n    #                LogText \"Result: ${I}: suhosin simulation mode is not active\"\n    #            else\n    #                LogText \"Result: ${I}: suhosin simulation mode is active\"\n    #            fi\n    #        done\n    #    fi\n\n    #    # Check Suhosin for PHP 7\n    #    if [ -n \"${MAJOR_VERSION}\" -a ${FOUND} -eq 1 ]; then\n    #        LogText \"Test: Check Suhosin for PHP 7 is not enabled\"\n    #        LogText \"Result: Suhosin for PHP 7 is in alpha stage and should not be used in production\"\n    #        ReportSuggestion \"${TEST_NO}\" \"Disable Suhosin for PHP 7\"\n    #        Display --indent 4 --text \"- Checking PHP suhosin extension status\" --result \"${STATUS_WARNING}\" --color RED\n    #        Display --indent 6 --text \"- Suhosin is enabled for PHP 7\" --result \"${STATUS_WARNING}\" --color RED\n    #        AddHP 0 1\n    #    elif [ -n \"${MAJOR_VERSION}\" -a ${FOUND} -eq 0 ]; then\n    #        LogText \"Test: Check Suhosin for PHP 7 is not enabled\"\n    #        LogText \"Result: Suhosin for PHP 7 is not enabled\"\n    #        Display --indent 4 --text \"- Checking PHP suhosin extension status\" --result \"${STATUS_OK}\" --color GREEN\n    #        Display --indent 6 --text \"- Suhosin is not enabled for PHP 7\" --result \"${STATUS_OK}\" --color GREEN\n    #        AddHP 1 1\n    #    else\n    #        if [ ${FOUND} -eq 0 ]; then\n    #            LogText \"Result: Suhosin extension is not enabled\"\n    #            Display --indent 4 --text \"- Checking PHP suhosin extension status\" --result \"${STATUS_WARNING}\" --color RED\n    #            ReportSuggestion \"${TEST_NO}\" \"Harden PHP by enabling suhosin extension\"\n    #            LogText \"suhosin extension is not enabled\"\n    #            AddHP 0 1\n    #        else\n    #            LogText \"Result: Suhosin extension is enabled\"\n    #            Display --indent 4 --text \"- Checking PHP suhosin extension status\" --result \"${STATUS_OK}\" --color GREEN\n    #            AddHP 2 2\n    #        fi\n\n    #        if [ \"${SIMULATION}\" = \"off\" ]; then\n    #            LogText \"Result: Suhosin simulation mode is not active\"\n    #            Display --indent 6 --text \"- Suhosin simulation mode status\" --result \"${STATUS_OK}\" --color GREEN\n    #            AddHP 2 2\n    #        else\n    #            LogText \"Result: Suhosin simulation mode is active\"\n    #            Display --indent 6 --text \"- Suhosin simulation mode status\" --result \"${STATUS_WARNING}\" --color RED\n    #            ReportSuggestion \"${TEST_NO}\" \"Harden PHP by deactivating suhosin simulation mode\"\n    #            LogText \"suhosin simulation mode is active\"\n    #            AddHP 0 1\n    #        fi\n    #    fi\n    #fi\n#\n#################################################################################\n#\n    # Test        : PHP-2382\n    # Description : Check listen option\n    # Background  : https://github.com/CISOfy/lynis/issues/837\n    if [ -n \"${PHPINI_ALLFILES}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PHP-2382 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check PHP expose_php option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        for FILE in ${PHPINI_ALLFILES}; do\n            # Don't look at this setting in cli configuration\n            case \"${FILE}\" in\n                */cli/*)\n                    continue\n                    ;;\n            esac\n            LogText \"Test: Checking file ${FILE}\"\n            FIND=$(${GREPBINARY} -E -i \"^listen = [0-9]{1,5}$\" ${FILE})\n            if HasData \"${FIND}\"; then\n                LogText \"Result: found listen on just a port number\"\n                LogText \"Data: ${FIND}\"\n                LogText \"Note: when possible, limit access to just localhost, so it can't be accessed from outside\"\n                FOUND=1\n            fi\n        done\n\n        if [ ${FOUND} -eq 1 ]; then\n            Display --indent 4 --text \"- Checking listen option\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            #ReportSuggestion \"${TEST_NO}\" \"Limit the listening of FastCGI to just localhost or a local socket\" \"listen = 127.0.0.1:9000\" \"-\"\n            AddHP 1 3\n        else\n            Display --indent 4 --text \"- Checking listen option\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_ports_packages",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Ports and packages\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_PORTS_AND_PACKAGES}\"\n    PACKAGE_MGR_PKG=0\n    PACKAGE_AUDIT_TOOL=\"\"\n    PACKAGE_AUDIT_TOOL_FOUND=0\n    PACMANCONF=\"${ROOTDIR}etc/pacman.conf\"\n    INSTALLED_PACKAGES=\"\"\n#\n#################################################################################\n#\n    Display --indent 2 --text \"- Searching package managers\"\n#\n#################################################################################\n#\n    # Test        : PKGS-7200\n    # Description : Check Alpine Package Keeper (apk)\n    if [ -x ${ROOTDIR}/sbin/apk ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7200 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Querying apk\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        Display --indent 4 --text \"- Searching apk package manager\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found apk binary\"\n        Report \"package_manager[]=apk\"\n        PACKAGE_MGR_PKG=1\n        LogText \"Test: Querying apk info -v to get package list\"\n        Display --indent 6 --text \"- Querying package manager\"\n        LogText \"Output:\"\n        SPACKAGES=$(apk info -v | ${SEDBINARY} -r -e 's/([a-z,A-Z,0-9,_,-,.]{1,250})-([a-z,A-Z,0-9,.]+-r[a-z,A-Z,0-9]+)/\\1,\\2/' | sort)\n        for J in ${SPACKAGES}; do\n            COUNT=$((COUNT + 1))\n            PACKAGE_NAME=$(echo ${J} | ${CUTBINARY} -d ',' -f1)\n            PACKAGE_VERSION=$(echo ${J} | ${CUTBINARY} -d ',' -f2)\n            LogText \"Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION}\"\n        done\n        Report \"installed_packages=${COUNT}\"\n    else\n        LogText \"Result: apk \"${STATUS_NOT_FOUND}\", test skipped\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7301\n    # Description : Query FreeBSD pkg\n    if [ -x ${ROOTDIR}usr/sbin/pkg ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7301 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Query FreeBSD pkg\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(pkg -N 2>&1; echo $?)\n        if [ \"${FIND}\" = \"0\" ]; then\n            Display --indent 4 --text \"- Searching packages with pkg\" --result \"${STATUS_FOUND}\" --color GREEN\n            Report \"package_manager[]=pkg\"\n            PACKAGE_MGR_PKG=1\n            LogText \"Result: Found pkg\"\n            LogText \"Test: Querying pkg to get package list\"\n            Display --indent 6 --text \"- Querying pkg for installed packages\"\n            LogText \"Output:\"; LogText \"-----\"\n            SPACKAGES=$(${ROOTDIR}usr/sbin/pkg query %n,%v)\n            for ITEM in ${SPACKAGES}; do\n                sPKG_NAME=$(echo ${ITEM} | ${CUTBINARY} -d ',' -f1)\n                sPKG_VERSION=$(echo ${ITEM} | ${CUTBINARY} -d ',' -f2)\n                LogText \"Installed package: ${sPKG_NAME} (version: ${sPKG_VERSION})\"\n                INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${ITEM}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7302\n    # Description : Query FreeBSD/NetBSD pkg_info\n    if [ -x ${ROOTDIR}usr/sbin/pkg_info ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7302 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Query FreeBSD/NetBSD pkg_info\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        Display --indent 4 --text \"- Checking pkg_info\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found pkg_info\"\n        Report \"package_manager[]=pkg_info\"\n        LogText \"Test: Querying pkg_info to get package list\"\n        Display --indent 6 --text \"- Querying pkg_info for installed packages\"\n        LogText \"Output:\"; LogText \"-----\"\n        SPACKAGES=$(${ROOTDIR}usr/sbin/pkg_info 2>&1 | ${SORTBINARY} | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f1 | ${SEDBINARY} -e 's/^\\(.*\\)-\\([0-9].*\\)$/\\1,\\2/g')\n        for ITEM in ${SPACKAGES}; do\n            COUNT=$((COUNT + 1))\n            sPKG_NAME=$(echo ${ITEM} | ${CUTBINARY} -d ',' -f1)\n            sPKG_VERSION=$(echo ${ITEM} | ${CUTBINARY} -d ',' -f2)\n            LogText \"Installed package: ${sPKG_NAME} (version: ${sPKG_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${ITEM}\"\n        done\n        Report \"installed_packages=${COUNT}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7303\n    # Description : Query brew package manager\n    FIND=$(which brew 2> /dev/null | grep -v \"no [^ ]* in \")\n    if [ -n \"${FIND}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7303 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Query brew package manager\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 4 --text \"- Searching brew\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found brew\"\n        PACKAGE_MGR_PKG=1\n        Report \"package_manager[]=brew\"\n        LogText \"Test: Querying brew to get package list\"\n        Display --indent 4 --text \"- Querying brew for installed packages\"\n        LogText \"Output:\"; LogText \"-----\"\n        GPACKAGES=$(brew list --versions)\n        while IFS= read -r PKG; do\n            PACKAGE_NAME=$(echo ${PKG} | ${CUTBINARY} -d ' ' -f1)\n            PACKAGE_VERSION=$(echo ${PKG} | ${CUTBINARY} -d ' ' -f2)\n            LogText \"Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION}\"\n        done << EOF\n$GPACKAGES\nEOF\n    else\n        LogText \"Result: brew can NOT be found on this system\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7304\n    # Description : Gentoo packages\n    if [ -x ${ROOTDIR}usr/bin/emerge -a -x ${ROOTDIR}usr/bin/equery ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7304 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Querying Gentoo packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 4 --text \"- Searching emerge\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found Gentoo emerge\"\n        Report \"package_manager[]=emerge\"\n        LogText \"Test: Querying portage to get package list\"\n        Display --indent 4 --text \"- Querying portage for installed packages\"\n        LogText \"Output:\"; LogText \"-----\"\n        GPACKAGES=$(equery l '*' | ${SEDBINARY} -e 's/[.*]//g')\n        for PKG in ${GPACKAGES}; do\n            LogText \"Found package ${PKG}\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PKG},0,\"\n        done\n    else\n        LogText \"Result: emerge can NOT be found on this system\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7305\n    # Description : Query macOS Apps in /Applications and CoreServices\n    Register --test-no PKGS-7305 --os macOS --weight L --network NO --category security --description \"Query macOS Apps in /Applications and CoreServices\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Querying Apps in /Applications\"\n        Display --indent 4 --text \"- Querying macOS Apps in /Applications\"\n        LogText \"Output:\"; LogText \"-----\"\n        for APP in /Applications/*.app; do\n            PACKAGE_NAME=$(basename \"$APP\" .app)\n            PACKAGE_VERSION=$(defaults read \"$APP/Contents/Info\" CFBundleShortVersionString 2>/dev/null || echo \"N/A\")\n            LogText \"Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION}\"\n        done\n        Display --indent 4 --text \"- Querying Apple CoreServices\"\n        for CS in /Library/Apple/System/Library/CoreServices/*.app; do\n            PACKAGE_NAME=$(basename \"$CS\" .app)\n            PACKAGE_VERSION=$(defaults read \"$CS/Contents/Info\" CFBundleShortVersionString 2>/dev/null || echo \"N/A\")\n            LogText \"Found CoreServices: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION}\"\n        done   \n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7306\n    # Description : Solaris packages\n    if [ -x ${ROOTDIR}usr/bin/pkginfo ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7306 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Querying Solaris packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        Display --indent 4 --text \"- Searching pkginfo\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found Solaris pkginfo\"\n            Report \"package_manager[]=pkginfo\"\n            PACKAGE_MGR_PKG=1\n            LogText \"Test: Querying pkginfo to get package list\"\n            Display --indent 4 --text \"- Querying pkginfo for installed packages\"\n            LogText \"Output:\"; LogText \"-----\"\n            # Strip SUNW from strings\n            SPACKAGES=$(${ROOTDIR}usr/bin/pkginfo -i | ${TRBINARY} -s ' ' | ${CUTBINARY} -d ' ' -f2 | ${SEDBINARY} \"s#^SUNW##\")\n            for J in ${SPACKAGES}; do\n                LogText \"Found package ${J}\"\n                INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${J},0,\"\n            done\n    else\n        LogText \"Result: pkginfo can NOT be found on this system\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7308\n    # Description : RPM package based systems\n    if [ -n \"${RPMBINARY}\" -a -z \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7308 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking package list with RPM\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        Display --indent 4 --text \"- Searching RPM package manager\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found rpm binary (${RPMBINARY})\"\n        Report \"package_manager[]=rpm\"\n        LogText \"Test: Querying 'rpm -qa' to get package list\"\n        Display --indent 6 --text \"- Querying RPM package manager\"\n        LogText \"Output:\"; LogText \"--------\"\n        SPACKAGES=$(${RPMBINARY} -qa --queryformat \"%{NAME},%{VERSION}-%{RELEASE}.%{ARCH}\\n\" 2> /dev/null | sort)\n        if [ -z \"${SPACKAGES}\" ]; then\n            LogText \"Result: RPM binary available, but package list seems to be empty\"\n            LogText \"Info: looks like the rpm binary is installed, but not used for package installation\"\n            ReportSuggestion \"${TEST_NO}\" \"Check RPM database as RPM binary available but does not reveal any packages\"\n        else\n            for PKG in ${SPACKAGES}; do\n                COUNT=$((COUNT + 1))\n                PACKAGE_NAME=$(echo ${PKG} | ${AWKBINARY} -F, '{print $1}')\n                PACKAGE_VERSION=$(echo ${PKG} | ${AWKBINARY} -F, '{print $2}')\n                LogText \"Found package: ${PKG}\"\n                INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION},\"\n            done\n            Report \"installed_packages=${COUNT}\"\n        fi\n    else\n        LogText \"Result: RPM binary NOT found on this system, test skipped\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7310\n    # Description : pacman package based systems\n    if [ -n \"${PACMANBINARY}\" -a -f \"${PACMANCONF}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7310 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking package list with pacman\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        Display --indent 4 --text \"- Searching pacman package manager\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found pacman binary (${PACMANBINARY})\"\n        Report \"package_manager[]=pacman\"\n        PACKAGE_MGR_PKG=1\n        LogText \"Test: Querying 'pacman -Q' to get package list\"\n        Display --indent 6 --text \"- Querying pacman package manager\"\n        LogText \"Output:\"; LogText \"--------\"\n        SPACKAGES=$(${PACMANBINARY} -Q | ${SORTBINARY} | ${SEDBINARY} 's/ /,/g')\n        if [ -z \"${SPACKAGES}\" ]; then\n            LogText \"Result: pacman binary available, but package list seems to be empty\"\n            LogText \"Info: looks like the pacman binary is installed, but not used for package installation\"\n        else\n            for PKG in ${SPACKAGES}; do\n                COUNT=$((COUNT + 1))\n                PACKAGE_NAME=$(echo ${PKG} | ${AWKBINARY} -F, '{ print $1 }')\n                PACKAGE_VERSION=$(echo ${PKG} | ${AWKBINARY} -F, '{ print $2 }')\n                LogText \"Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n                INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PKG}\"\n            done\n            Report \"installed_packages=${COUNT}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7312\n    # Description : Check for available package updates when pacman package is used\n    if [ -n \"${PACMANBINARY}\" -a -f \"${PACMANCONF}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7312 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking available updates for pacman based system\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        FIND=$(which checkupdates 2> /dev/null | grep -v \"no [^ ]* in \")\n        if [ -n \"${FIND}\" ]; then\n            FIND=$(checkupdates)\n            for I in ${FIND}; do\n                LogText \"Result: update available for ${I}\"\n                Report \"available_update[]=${I}\"\n                FOUND=1\n            done\n            if [ ${FOUND} -eq 1 ]; then\n                Display --indent 4 --text \"- Searching update status (checkupdates)\" --result \"OUTDATED\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Perform update of system updates as this system uses rolling updates\"\n            else\n                Display --indent 4 --text \"- Searching update status (checkupdates)\" --result \"UP-TO-DATE\" --color GREEN\n            fi\n        else\n            LogText \"Result: skipping this test, can't find checkupdates binary\"\n        fi\n    else\n        LogText \"Result: pacman binary NOT found on this system, test skipped\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7314\n    # Description : Check pacman.conf options\n    if [ -n \"${PACMANBINARY}\" -a -f \"${PACMANCONF}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7314 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking pacman configuration options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        # Check configuration options (options start with a capital)\n        LogText \"Test: searching configured options in ${PACMANCONF}\"\n        FIND=$(${GREPBINARY} \"^[A-Z]\" ${PACMANCONF} | ${SORTBINARY} -u | ${SEDBINARY} 's/ /:space:/g')\n        for I in ${FIND}; do\n            PMOPTION=$(echo ${I} | ${SEDBINARY} 's/:space:/ /g' | ${AWKBINARY} -F= '{ print $1 }')\n            PMVALUE=$(echo ${I} | ${SEDBINARY} 's/:space:/ /g' | ${AWKBINARY} -F= '{ print $2 }')\n            LogText \"Result: found option ${PMOPTION} configured with value ${PMVALUE}\"\n            Report \"pacman_option[]=${PMOPTION}:${PMVALUE}:\"\n        done\n\n        # Check software repositories\n        LogText \"Test: checking available repositories\"\n        FIND=$(${GREPBINARY} \"^\\[.*\\]$\" ${PACMANCONF} | ${TRBINARY} -d '[]')\n        for I in ${FIND}; do\n            COUNT=$((COUNT + 1))\n            Report \"package_repository[]=${I}\"\n        done\n        LogText \"Result: found ${COUNT} repositories\"\n    fi\n#\n#################################################################################\n#\n    # TODO\n\n    ## Test        : PKGS-7318\n    ## Description : APT configuration\n    #if [ -x ${ROOTDIR}usr/bin/apt-config ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    #Register --test-no PKGS-7318 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"APT configuration\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    #    LogText \"Test: check APT configuration\"\n    #    if ! SkipAtomicTest ${TEST_NO}:atomicname; then\n    #    # Acquire::AllowInsecureRepositories should be 0 (could be 1)\n    #    # Acquire::AllowDowngradeToInsecureRepositories should be 0\n    #    # Binary::apt::Acquire::AllowInsecureRepositories should be 0\n    #fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7320\n    # Description : Check available of arch-audit\n    if [ \"${OS_FULLNAME}\" = \"Arch Linux\" ] || [ \"${OS_FULLNAME}\" = \"Arch Linux 32\" ] || [ \"${OS_FULLNAME}\" = \"Garuda Linux\" ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"Test only applies to Arch Linux and Garuda Linux\"; fi\n    Register --test-no PKGS-7320 --os \"Linux\" --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Checking for arch-audit tooling\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -z \"${ARCH_AUDIT_BINARY}\" ]; then\n            LogText \"Result: no arch-audit binary found\"\n            AddHP 1 2\n            ReportSuggestion \"${TEST_NO}\" \"Consider installing arch-audit to determine vulnerable packages\" \"arch-audit\" \"text:Install arch-audit\"\n        else\n            PACKAGE_AUDIT_TOOL_FOUND=1\n            PACKAGE_AUDIT_TOOL=\"arch-audit\"\n            LogText \"Result: arch-audit binary found (${ARCH_AUDIT_BINARY})\"\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7322\n    # Description : Discover vulnerable packages with arch-audit\n    if [ -n \"${ARCH_AUDIT_BINARY}\" ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"arch-audit not found\"; fi\n    Register --test-no PKGS-7322 --os \"Linux\" --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Discover vulnerable packages with arch-audit\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking arch-audit output for vulnerable packages\"\n        FIND=$(${ARCH_AUDIT_BINARY} | ${SEDBINARY} 's/ High risk!//' | ${SEDBINARY} 's/ Medium risk!//' | ${SEDBINARY} 's/ Low risk!//' | ${SEDBINARY} 's/\\.\\..*$//' | ${SEDBINARY} 's/, /,/g' | ${SEDBINARY} 's/\\(\\[\"\\|\"\\]\\)//g' | ${SEDBINARY} 's/\"\"/,/g' | ${AWKBINARY} '{if ($0 ~ /is affected by CVE\\-/) {print $1\"|\"$5\"|\"} else {ORS=\"\"; print $1\"|\"; for (i=5; i<=NF; i++)print $i; print \"\\n\"; ORS=\"\\n\"}}'| ${AWKBINARY} -F'|' 'NF>1{a[$1] = a[$1]\",\"$2}END{for(i in a){print i\"\"a[i]\"|\"}}' | ${SEDBINARY} 's/,CVE-/|cve=CVE-/' | ${SORTBINARY})\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: no vulnerable packages found with arch-audit\"\n            AddHP 10 10\n        else\n            LogText \"Result: found one or more vulnerable packages\"\n            VULNERABLE_PACKAGES_FOUND=1\n            for ITEM in ${FIND}; do\n                LogText \"Found line: ${ITEM}\"\n                Report \"vulnerable_package[]=${ITEM}\"\n                AddHP 1 2\n            done\n            ReportWarning \"${TEST_NO}\" \"Vulnerable packages found\" \"arch-audit has output\" \"text:Run arch-audit to see the output, and when needed update the packages with pacman -Suy\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7328\n    # Description : Check installed packages with Zypper\n    if [ -n \"${ZYPPERBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7328 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Querying Zypper for installed packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        PACKAGE_AUDIT_TOOL_FOUND=1\n        PACKAGE_AUDIT_TOOL=\"zypper\"\n        FIND=$(${ZYPPERBINARY} --non-interactive -n se -t package -i | ${AWKBINARY} '{ if ($1==\"i\") { print $3 } }')\n        if [ -n \"${FIND}\" ]; then\n            for PKG in ${FIND}; do\n                COUNT=$((COUNT + 1))\n                LogText \"Installed package: ${PKG}\"\n                INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PKG},0,\"\n            done\n            Report \"installed_packages=${COUNT}\"\n        else\n            # Could not find any installed packages\n            ReportException \"${TEST_NO}\" \"No installed packages found with Zypper\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7330\n    # Description : Check vulnerable packages with Zypper\n    if [ -n \"${ZYPPERBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7330 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Querying Zypper for vulnerable packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${ZYPPERBINARY} --non-interactive pchk | ${GREPBINARY} \"(0 security patches)\")\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: No security updates found with Zypper\"\n            Display --indent 2 --text \"- Using Zypper to find vulnerable packages\" --result \"${STATUS_NONE}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Using Zypper to find vulnerable packages\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Zypper found one or more installed packages which are vulnerable.\"\n            ReportWarning \"${TEST_NO}\" \"Found one or more vulnerable packages installed\"\n            # Unfortunately zypper does not properly give back which package it is. Usually best guess is last word on the line\n            FIND=$(${ZYPPERBINARY} --non-interactive lp | ${AWKBINARY} '{ if ($5==\"security\" || $7==\"security\") { print $NF }}' | ${SEDBINARY} 's/:$//' | ${GREPBINARY} -v \"^$\" | ${SORTBINARY} -u)\n            LogText \"List of vulnerable packages/version:\"\n            for PKG in ${FIND}; do\n                VULNERABLE_PACKAGES_FOUND=1\n                Report \"vulnerable_package[]=${PKG}\"\n                LogText \"Vulnerable package: ${PKG}\"\n                # Decrease hardening points for every found vulnerable package\n                AddHP 1 2\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7332\n    # Description : Query macOS ports\n    if [ -x ${ROOTDIR}opt/local/bin/port ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7332 --os \"macOS\" --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query macOS ports\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${ROOTDIR}opt/local/bin/port installed 2>&1 | ${GREPBINARY} active | ${SORTBINARY}; ${ROOTDIR}bin/echo $?)\n        if [ \"${FIND}\" = \"0\" ]; then\n            Display --indent 4 --text \"- Searching packages with port\" --result \"{STATUS_FOUND}\" --color GREEN\n            Report \"package_manager[]=port\"\n            PACKAGE_MGR_PKG=1\n            LogText \"Result: Found port utility\"\n            LogText \"Test: Querying port to get package list\"\n            Display --indent 6 --text \"- Querying port for installed packages\"\n            LogText \"Output:\"; LogText \"-----\"\n            SPACKAGES=$(${ROOTDIR}opt/local/bin/port installed | ${GREPBINARY} active)\n            for ITEM in ${SPACKAGES}; do\n                SPORT_NAME=$(echo ${ITEM} | ${CUTBINARY} -d@ -f1)\n                SPORT_VERSION=$(echo ${ITEM} | ${CUTBINARY} -d@ -f2 | ${CUTBINARY} -d' ' -f1)\n                LogText \"Installed package: ${SPORT_NAME} (version: ${SPORT_VERSION})\"\n                INSTALLED_PACKAGES=\"${INSTALLED_PORTS}|${ITEM}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7334\n    # Description : Query macOS ports for available port upgrades\n    if [ -x ${ROOTDIR}opt/local/bin/port ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7334 --os \"macOS\" --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Query port for port upgrades\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: Querying ports for possible port upgrades\"\n        UPACKAGES=$(${ROOTDIR}opt/local/bin/port outdated 2> /dev/null | ${CUTBINARY} -d' ' -f1)\n        for J in ${UPACKAGES}; do\n            COUNT=$((COUNT + 1))\n            LogText \"Upgrade available (new version): ${J}\"\n            Report \"upgrade_available[]=${J}\"\n        done\n        Report \"upgrade_available_count=${COUNT}\"\n        if [ ${COUNT} -eq 0 ]; then\n            LogText \"Result: no upgrades found\"\n            Display --indent 2 --text \"- Checking ports for updates\" --result \"${STATUS_NONE}\" --color GREEN\n            AddHP 2 2\n        else\n            Display --indent 2 --text \"- Checking ports for updates\" --result \"${STATUS_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7345\n    # Description : Debian package based systems (dpkg)\n    if [ -x ${ROOTDIR}usr/bin/dpkg ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7345 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Querying dpkg\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        Display --indent 4 --text \"- Searching dpkg package manager\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: Found dpkg binary\"\n        Report \"package_manager[]=dpkg\"\n        PACKAGE_MGR_PKG=1\n        LogText \"Test: Querying dpkg -l to get package list\"\n        Display --indent 6 --text \"- Querying package manager\"\n        LogText \"Output:\"\n        SPACKAGES=$(dpkg -l 2>/dev/null | ${GREPBINARY} \"^ii\" | ${TRBINARY} -s ' ' | ${TRBINARY} ' ' ',' | sort)\n        for J in ${SPACKAGES}; do\n            COUNT=$((COUNT + 1))\n            PACKAGE_NAME=$(echo ${J} | ${CUTBINARY} -d ',' -f2)\n            PACKAGE_VERSION=$(echo ${J} | ${CUTBINARY} -d ',' -f3)\n            LogText \"Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION}\"\n        done\n        Report \"installed_packages=${COUNT}\"\n    else\n        LogText \"Result: dpkg can NOT be found on this system, test skipped\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7346\n    # Description : Check packages which are removed, but still own configuration files, cron jobs etc\n    # Notes       : Cleanup: for pkg in $(dpkg -l | ${GREPBINARY} \"^rc\" | ${CUTBINARY} -d' ' -f3); do aptitude purge ${pkg}; done\n    if [ -x ${ROOTDIR}usr/bin/dpkg ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7346 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Search unpurged packages on system\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: Querying dpkg -l to get unpurged packages\"\n        SPACKAGES=$(${ROOTDIR}usr/bin/dpkg -l 2>/dev/null | ${GREPBINARY} \"^rc\" | ${CUTBINARY} -d ' ' -f3 | sort)\n        if [ -z \"${SPACKAGES}\" ]; then\n            Display --indent 4 --text \"- Query unpurged packages\" --result \"${STATUS_NONE}\" --color GREEN\n            LogText \"Result: no packages found with left overs\"\n        else\n            Display --indent 4 --text \"- Query unpurged packages\" --result \"${STATUS_FOUND}\" --color YELLOW\n            LogText \"Result: found one or more packages with left over configuration files, cron jobs etc\"\n            LogText \"Output:\"\n            for J in ${SPACKAGES}; do\n                COUNT=$((COUNT + 1))\n                LogText \"Found unpurged package: ${J}\"\n            done\n            ReportSuggestion \"${TEST_NO}\" \"Purge old/removed packages (${COUNT} found) with aptitude purge or dpkg --purge command. This will cleanup old configuration files, cron jobs and startup scripts.\"\n        fi\n    else\n        LogText \"Result: dpkg can NOT be found on this system, test skipped\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7348\n    # Description : Show unneeded distfiles if present\n    # Notes       : Portsclean seems to be gone from the ports, so no suggestion or warning is\n    #               issued when it's missing.\n    #               Add portmaster --clean-distfiles-all\n    Register --test-no PKGS-7348 --os FreeBSD --weight L --network NO --category security --description \"Check for old distfiles\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -x ${ROOTDIR}usr/local/sbin/portsclean ]; then\n            FIND=$(${ROOTDIR}usr/local/sbin/portsclean -n -DD | ${GREPBINARY} 'Delete' | wc -l | ${TRBINARY} -d ' ')\n            if [ ${FIND} -eq 0 ]; then\n                Display --indent 2 --text \"- Checking presence old distfiles\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: no unused distfiles found\"\n            else\n                Display --indent 2 --text \"- Checking presence old distfiles\" --result \"${STATUS_WARNING}\" --color YELLOW\n                LogText \"Result: found ${FIND} unused distfiles\"\n                ReportSuggestion \"${TEST_NO}\" \"Unused distfiles found. Use portsclean to delete these files. For example: portsclean -DD.\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7350\n    # Description : Use Dandified YUM to gather installed packages\n    # Notes       : Possible replacement for YUM in the long term\n    if [ -n \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no \"PKGS-7350\" --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking for installed packages with DNF utility\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        Display --indent 4 --text \"- Searching DNF package manager\" --result \"${STATUS_FOUND}\" --color GREEN\n        LogText \"Result: found DNF (Dandified YUM) utility (binary: ${DNFBINARY})\"\n        Report \"package_manager[]=dnf\"\n        Display --indent 6 --text \"- Querying DNF package manager\"\n\n        PACKAGE_AUDIT_TOOL_FOUND=1\n        PACKAGE_AUDIT_TOOL=\"dnf\"\n        SPACKAGES=$(${DNFBINARY} -q list installed 2> /dev/null | ${AWKBINARY} '{ if ($1!=\"Installed\" && $1!=\"Last\") {print $1\",\"$2 }}')\n        for PKG in ${SPACKAGES}; do\n            COUNT=$((COUNT + 1))\n            PACKAGE_NAME=$(echo ${PKG} | ${CUTBINARY} -d ',' -f1)\n            PACKAGE_VERSION=$(echo ${PKG} | ${CUTBINARY} -d ',' -f2)\n            LogText \"Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})\"\n            INSTALLED_PACKAGES=\"${INSTALLED_PACKAGES}|${PACKAGE_NAME},${PACKAGE_VERSION}\"\n        done\n        Report \"installed_packages=${COUNT}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7352\n    # Description : Use Dandified YUM to detect security updates\n    if [ -n \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no \"PKGS-7352\" --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking for security updates with DNF utility\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check for security updates\n        LogText \"Action: checking updateinfo for security updates\"\n        FIND=$(${DNFBINARY} -q updateinfo list sec 2> /dev/null | ${AWKBINARY} '{ if ($2==\"security\") { print $3 }}')\n        if [ -n \"${FIND}\" ]; then\n            VULNERABLE_PACKAGES_FOUND=1\n            LogText \"Result: found vulnerable packages, upgrade of system needed.\"\n            for PKG in ${FIND}; do\n                Report \"vulnerable_package[]=${PKG}\"\n                LogText \"Vulnerable package: ${PKG}\"\n                # Decrease hardening points for every found vulnerable package\n                AddHP 1 2\n            done\n            ReportWarning \"${TEST_NO}\" \"Found one or more vulnerable packages. Run: dnf upgrade\"\n            Display --indent 2 --text \"- Using DNF to find vulnerable packages\" --result \"${STATUS_WARNING}\" --color RED\n        else\n            LogText \"Result: no security updates found\"\n            Display --indent 2 --text \"- Using DNF to find vulnerable packages\" --result \"${STATUS_NONE}\" --color GREEN\n            AddHP 5 5\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7354\n    # Description : Perform integrity tests for package database\n    if [ -n \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no \"PKGS-7354\" --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking package database integrity\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check if repoquery plugin is available\n        FIND=$(${DNFBINARY} 2>&1 | ${GREPBINARY} \"^repoquery\")\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Action: checking integrity of package database\"\n            FIND=$(${DNFBINARY} -q repoquery --duplicated)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found unexpected result on repoquery --duplicated\"\n                ReportSuggestion \"${TEST_NO}\" \"Check output of: dnf repoquery --duplicated\"\n            fi\n            FIND=$(${DNFBINARY} -q repoquery --unsatisfied)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found unexpected result on repoquery --unsatisfied\"\n                ReportSuggestion \"${TEST_NO}\" \"Check output of: dnf repoquery --unsatisfied\"\n            fi\n        else\n            LogText \"Result: repoquery plugin not installed.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7366\n    # Description : Checking if debsecan is installed and enabled on Debian systems\n    if [ -n \"${DEBSECANBINARY}\" ] && ( [ \"${LINUX_VERSION}\" = \"Debian\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"Debian\" ] ); then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no \"PKGS-7366\" --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --category security --description \"Checking for debsecan utility\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${DEBSECANBINARY}\" ]; then\n            LogText \"Result: debsecan utility is installed\"\n            Display --indent 4 --text \"- debsecan utility\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n            PACKAGE_AUDIT_TOOL_FOUND=1\n            PACKAGE_AUDIT_TOOL=\"debsecan\"\n            FIND=$(${FINDBINARY} ${ROOTDIR}etc/cron* -name debsecan)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: cron job is configured for debsecan\"\n                Display --indent 6 --text \"- debsecan cron job\" --result \"${STATUS_FOUND}\" --color GREEN\n                AddHP 3 3\n            else\n                LogText \"Result: no cron job is configured for debsecan\"\n                Display --indent 4 --text \"- debsecan cron job\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                AddHP 1 3\n                ReportSuggestion \"${TEST_NO}\" \"Check debsecan cron job and ensure it is enabled\"\n            fi\n        else\n            LogText \"Result: debsecan is not installed.\"\n            Display --indent 4 --text \"- debsecan utility\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            AddHP 0 2\n            ReportSuggestion \"${TEST_NO}\" \"Install debsecan to check for vulnerabilities on installed packages.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7370\n    # Description : Checking debsums installation status and presence in cron job\n    # Note        : Run this only when it is a DPKG based system\n    if [ -n \"${DPKGBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no \"PKGS-7370\" --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking for debsums utility\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${DEBSUMSBINARY}\" ]; then\n            LogText \"Result: debsums utility is installed\"\n            Display --indent 4 --text \"- debsums utility\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 1 1\n            # Check in /etc/cron.hourly, daily, weekly, monthly etc\n            COUNT=$(find /etc/cron* -name debsums | wc -l)\n            if [ ${COUNT} -gt 0 ]; then\n                CRON_CHECK=\"\"\n                if [ -f ${ROOTDIR}etc/default/debsums ]; then\n                    CRON_CHECK=$(${GREPBINARY} CRON_CHECK /etc/default/debsums|${AWKBINARY} -F \"=\" '{print $2}')\n                fi\n                if [ \"${CRON_CHECK}\" = \"daily\" ] || [ \"${CRON_CHECK}\" = \"weekly\" ] || [ \"${CRON_CHECK}\" = \"monthly\" ]; then\n                    LogText \"Result: Cron job is configured for debsums utility.\"\n                    Display --indent 6 --text \"- Cron job for debsums\" --result \"${STATUS_FOUND}\" --color GREEN\n                    AddHP 3 3\n                else\n                    LogText \"Result: Cron job is not configured for debsums utility.\"\n                    Display --indent 6 --text \"- Cron job for debsums\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                    AddHP 1 3\n                    ReportSuggestion \"${TEST_NO}\" \"Check debsums configuration and enable checking regularly via a cron job (CRON_CHECK in default file).\"\n                fi\n            else\n                LogText \"Result: Cron job is not configured for debsums utility.\"\n                Display --indent 6 --text \"- Cron job for debsums\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                AddHP 1 3\n                ReportSuggestion \"${TEST_NO}\" \"Check debsums configuration and enable checking regularly via a cron job.\"\n            fi\n        else\n            LogText \"Result: debsums utility is not installed.\"\n            AddHP 0 2\n            ReportSuggestion \"${TEST_NO}\" \"Install debsums utility for the verification of packages with known good database.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7378\n    # Description : Query FreeBSD portmaster for available port upgrades\n    if [ -x ${ROOTDIR}usr/local/sbin/portmaster ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7378 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Query portmaster for port upgrades\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: Querying portmaster for possible port upgrades\"\n        UPACKAGES=$(${ROOTDIR}usr/local/sbin/portmaster -L | ${GREPBINARY} \"version available\" | ${AWKBINARY} '{ print $5 }')\n        for PKG in ${UPACKAGES}; do\n            COUNT=$((COUNT + 1))\n            LogText \"Upgrade available (new version): ${PKG}\"\n            Report \"upgrade_available[]=${PKG}\"\n        done\n        Report \"upgrade_available_count=${COUNT}\"\n        if [ ${COUNT} -eq 0 ]; then\n            LogText \"Result: no updates found\"\n            Display --indent 2 --text \"- Checking portmaster for updates\" --result \"${STATUS_NONE}\" --color GREEN\n        else\n            LogText \"Result: found ${COUNT} updates\"\n            Display --indent 2 --text \"- Checking portmaster for updates\" --result \"${STATUS_FOUND}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7380\n    # Description : Check for vulnerable NetBSD packages (with pkg_admin)\n    Register --test-no PKGS-7380 --os NetBSD --weight L --network NO --category security --description \"Check for vulnerable NetBSD packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -x ${ROOTDIR}usr/sbin/pkg_admin ]; then\n            PACKAGE_AUDIT_TOOL_FOUND=1\n            PACKAGE_AUDIT_TOOL=\"pkg_admin audit\"\n            if [ -f ${ROOTDIR}var/db/pkg/pkg-vulnerabilities ]; then\n                FIND=$(${ROOTDIR}usr/sbin/pkg_admin audit)\n                if [ -z \"${FIND}\" ]; then\n                    LogText \"Result: pkg_admin audit results are clean\"\n                    Display --indent 2 --text \"- Checking pkg_admin audit to obtain vulnerable packages\" --result \"${STATUS_NONE}\" --color GREEN\n                    AddHP 10 10\n                else\n                    Display --indent 2 --text \"- Checking pkg_admin audit to obtain vulnerable packages\" --result \"${STATUS_WARNING}\" --color RED\n                    LogText \"Result: pkg_admin audit found one or more installed packages which are vulnerable.\"\n                    ReportWarning \"${TEST_NO}\" \"Found one or more vulnerable packages.\"\n                    LogText \"List of vulnerable packages/version:\"\n                    for I in $(${ROOTDIR}usr/sbin/pkg_admin audit | ${AWKBINARY} '{ print $2 }' | ${SORTBINARY} -u); do\n                        VULNERABLE_PACKAGES_FOUND=1\n                        Report \"vulnerable_package[]=${I}\"\n                        LogText \"Vulnerable package: ${I}\"\n                        # Decrease hardening points for every found vulnerable package\n                        AddHP 1 2\n                    done\n                fi\n            else\n                ReportSuggestion \"${TEST_NO}\" \"Fetch the package database with pkg_admin fetch-pkg-vulnerabilities\"\n                AddHP 0 2\n            fi\n        else\n            Display --indent 2 --text \"- pkg_admin audit not installed\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: pkg_admin audit not installed, skipping this vulnerability test.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7381\n    # Description : Check for vulnerable FreeBSD packages (with pkg)\n    # Notes       : Related vulnerability file is /var/db/pkg/vuln.xml\n    # TODO        : Run this in any jail\n    if [ -n \"${PKG_BINARY}\" ]; then PREQS_MET=\"YES\"; SKIPREASON=\"\"; else PREQS_MET=\"NO\"; SKIPREASON=\"pkg tool not available\"; fi\n    Register --test-no PKGS-7381 --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight L --network NO --category security --description \"Check for vulnerable FreeBSD packages with pkg\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        PACKAGE_AUDIT_TOOL_FOUND=1\n        PACKAGE_AUDIT_TOOL=\"pkg audit\"\n        if [ -f ${ROOTDIR}var/db/pkg/vuln.xml ]; then\n            # Query pkg audit, with optional refresh of vulnerability data (-F)\n            if [ ${REFRESH_REPOSITORIES} -eq 1 ]; then\n                FIND=$(${PKG_BINARY} audit -F -q 2> /dev/null)\n            else\n                FIND=$(${PKG_BINARY} audit -q 2> /dev/null)\n            fi\n            if [ $? -eq 0 ]; then\n                LogText \"Result: pkg audit results are clean\"\n                Display --indent 2 --text \"- Checking pkg audit to obtain vulnerable packages\" --result \"${STATUS_NONE}\" --color GREEN\n                AddHP 10 10\n            elif [ $? -eq 1 ]; then\n                if [ -n \"${FIND}\" ]; then\n                    VULNERABLE_PACKAGES_FOUND=1\n                    Display --indent 2 --text \"- Checking pkg audit to obtain vulnerable packages\" --result \"${STATUS_FOUND}\" --color YELLOW\n                    for ITEM in ${FIND}; do\n                        COUNT=$((COUNT + 1))\n                        Report \"vulnerable_package[]=${ITEM}\"\n                        LogText \"Vulnerable package: ${ITEM}\"\n                        AddHP 1 2\n                    done\n                    ReportWarning \"${TEST_NO}\" \"Found vulnerable packages\" \"${COUNT} vulnerable packages\" \"text:Run pkg audit\"\n                else\n                    LogText \"Result: found an exit code greater than zero, yet no output\"\n                fi\n            else\n                LogText \"Result: exited with code $?\"\n                ReportException \"${TEST_NO}\" \"Found an unknown exit code for pkg audit. Please create an issue at ${PROJECT_SOURCE}\"\n            fi\n        else\n            LogText \"Result: could not find vulnerability database\"\n            ReportWarning \"${TEST_NO}\" \"No vulnerability database available\" \"pkg audit\" \"text:Run pkg audit -F\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7382\n    # Description : Check for vulnerable FreeBSD packages\n    # Notes       : Newer machines should use pkg audit instead of portaudit\n    if [ -x ${ROOTDIR}usr/local/sbin/portaudit ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7382 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for vulnerable FreeBSD packages with portaudit\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        PACKAGE_AUDIT_TOOL_FOUND=1\n        FIND=$(${ROOTDIR}usr/local/sbin/portaudit | ${GREPBINARY} 'problem(s) in your installed packages found' | ${GREPBINARY} -v '0 problem(s) in your installed packages found')\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: Portaudit results are clean\"\n            Display --indent 2 --text \"- Checking portaudit to obtain vulnerable packages\" --result \"${STATUS_NONE}\" --color GREEN\n            AddHP 10 10\n        else\n            Display --indent 2 --text \"- Checking portaudit to obtain vulnerabilities\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Portaudit found one or more installed packages which are vulnerable.\"\n            ReportWarning \"${TEST_NO}\" \"Found one or more vulnerable packages.\"\n            ReportSuggestion \"${TEST_NO}\" \"Update your system with portupgrade or other tools\"\n            LogText \"List of vulnerable packages/version:\"\n            for PKG in $(${ROOTDIR}usr/local/sbin/portaudit | ${GREPBINARY} \"Affected package\" | ${CUTBINARY} -d ' ' -f3 | ${SORTBINARY} -u); do\n                VULNERABLE_PACKAGES_FOUND=1\n                Report \"vulnerable_package[]=${PKG}\"\n                LogText \"Vulnerable package: ${PKG}\"\n                # Decrease hardening points for every found vulnerable package\n                AddHP 1 2\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7383\n    # Description : Check for YUM package Update management\n    # Notes       : Skip if DNF is used as package manager\n    if [ -n \"${YUMBINARY}\" -a -z \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7383 --preqs-met ${PREQS_MET} --os Linux --weight M --network NO --category security --description \"Check for YUM package update management\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: YUM package update management\"\n        FIND=$(${YUMBINARY} repolist 2>/dev/null | ${GREPBINARY} repolist | ${SEDBINARY} 's/[[:blank:]]//g' | ${SEDBINARY} 's/[,.]//g' | ${AWKBINARY} -F \":\" '{print $2}' | ${GREPBINARY} -E \"^[0-9]+$\")\n        if [ -z \"${FIND}\" -o \"${FIND}\" = \"0\" ]; then\n            LogText \"Result: YUM package update management failed\"\n            Display --indent 2 --text \"- YUM package management consistency\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"YUM is not properly configured or registered for this platform (no repolist found)\"\n        else\n            LogText \"Result: YUM repository available (${FIND})\"\n            Display --indent 2 --text \"- YUM package management consistency\" --result \"${STATUS_OK}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7384\n    # Description : Search for YUM utils package\n    if [ -n \"${YUMBINARY}\" -a -z \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7384 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --category security --description \"Check for YUM utils package\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # package-cleanup tool can be found in different locations\n        if [ -x ${ROOTDIR}bin/package-cleanup -o -x ${ROOTDIR}usr/bin/package-cleanup ]; then\n            LogText \"Result: found YUM utils package (package-cleanup)\"\n            # Check for duplicates\n            LogText \"Test: Checking for duplicate packages\"\n            FIND=$(package-cleanup -q --dupes > /dev/null; echo $?)\n            if [ \"${FIND}\" = \"0\" ]; then\n                LogText \"Result: No duplicate packages found\"\n                Display --indent 2 --text \"- Checking package database duplicates\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: One or more duplicate packages found\"\n                Display --indent 2 --text \"- Checking package database duplicates\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"Found one or more duplicate packages installed\"\n                ReportSuggestion \"${TEST_NO}\" \"Run package-cleanup to solve duplicate package problems\"\n            fi\n\n            # Check for package database problems\n            LogText \"Test: Checking for database problems\"\n            FIND=$(package-cleanup --problems > /dev/null; echo $?)\n            if [ \"${FIND}\" = \"0\" ]; then\n                LogText \"Result: No package database problems found\"\n                Display --indent 2 --text \"- Checking package database for problems\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: One or more problems found in package database\"\n                Display --indent 2 --text \"- Checking package database for problems\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"Found one or more problems in the package database\"\n                ReportSuggestion \"${TEST_NO}\" \"Run package-cleanup to solve package problems\"\n            fi\n        else\n            Display --indent 2 --text \"- yum-utils package not installed\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: YUM utils package not found\"\n            ReportSuggestion \"${TEST_NO}\" \"Install package 'yum-utils' for better consistency checking of the package database\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7386\n    # Description : Search for YUM security package\n    # Notes       : This test does not apply to CentOS and clones, as --security is not available\n    #             : RHEL 7: plugin default installed\n    #             : RHEL 6: yum-security-plugin (plugin)\n    #             : RHEL 5: yum-security (plugin)\n    if [ -x ${ROOTDIR}usr/bin/yum -a -z \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7386 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --category security --description \"Check for YUM security package\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        DO_TEST=0\n        LogText \"Test: Determining if yum-security package installed\"\n\n        # Check for built-in --security option\n        if [ ${DO_TEST} -eq 0 ]; then\n            FileExists ${ROOTDIR}usr/share/yum-cli/cli.py\n            if [ ${FILE_FOUND} -eq 1 ]; then\n                if SearchItem \"\\-\\-security\" \"${ROOTDIR}usr/share/yum-cli/cli.py\"; then\n                    DO_TEST=1\n                    LogText \"Result: found built-in security in yum\"\n                else\n                    LogText \"Result: did not find --security in ${ROOTDIR}usr/share/yum-cli/cli.py\"\n                fi\n            fi\n        fi\n\n        if [ ${DO_TEST} -eq 0 ]; then\n            FileExists ${ROOTDIR}etc/yum/pluginconf.d/security.conf\n            if [ ${FILE_FOUND} -eq 1 ]; then\n                if SearchItem \"^enabled=1$\" \"${ROOTDIR}etc/yum/pluginconf.d/security.conf\"; then\n                    DO_TEST=1\n                    LogText \"Result: found enabled plugin\"\n                else\n                    LogText \"Result: plugin NOT enabled in ${ROOTDIR}etc/yum/pluginconf.d/security.conf\"\n                fi\n            fi\n        fi\n\n        # Check if it's installed as package (this is old style)\n        if [ ${DO_TEST} -eq 0 ]; then\n            FIND=$(rpm -q yum-security yum-plugin-security | ${GREPBINARY} -v \"not installed\")\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: found yum-plugin-security package\"\n                DO_TEST=1\n            fi\n        fi\n\n        # If we have the module of yum active, continue testing\n        if [ ${DO_TEST} -eq 1 ]; then\n            PACKAGE_AUDIT_TOOL_FOUND=1\n            PACKAGE_AUDIT_TOOL=\"yum-security\"\n            LogText \"Test: Checking for vulnerable packages\"\n            FIND2=$(${ROOTDIR}usr/bin/yum list-sec security | ${AWKBINARY} '{ if($2==\"security\" || $2~\"Sec\") print $3\",\"$5 }')\n            if [ -z \"${FIND2}\" ]; then\n                LogText \"Result: no vulnerable packages found\"\n                Display --indent 2 --text \"- Checking missing security packages\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: found vulnerable package(s)\"\n                Display --indent 2 --text \"- Checking missing security packages\" --result \"${STATUS_WARNING}\" --color RED\n                for I in ${FIND2}; do\n                    VULNERABLE_PACKAGES_FOUND=1\n                    Report \"vulnerable_package[]=${I}\"\n                    LogText \"Vulnerable package: ${I}\"\n                    AddHP 1 2\n                done\n                ReportWarning \"${TEST_NO}\" \"Found one or more vulnerable packages.\"\n            fi\n        else\n            LogText \"Result: yum-security package not found\"\n            Display --indent 2 --text \"- Checking missing security packages\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Install package yum-plugin-security if possible, to maintain security updates easier (yum install yum-plugin-security)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7387\n    # Description : Search for YUM GPG check\n    if [ -x ${ROOTDIR}usr/bin/yum -a -z \"${DNFBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7387 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --category security --description \"Check for GPG signing in YUM security package\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${PYTHONBINARY}\" ]; then\n            LogText \"Test: checking enabled repositories\"\n            REPOS=$(${PYTHONBINARY} -c 'import yum ; yb = yum.YumBase() ; yb.conf ; print [(r.id + \"=\" + str(r.gpgcheck)) for r in yb.repos.listEnabled()]' | ${GREPBINARY} \"^\\[\" | ${TRBINARY} -d '[] ' | ${TRBINARY} -d \"'\" | ${SEDBINARY} 's/,/ /g')\n            if [ -z \"${REPOS}\" ]; then LogText \"Result: found no repositories\"; fi\n            for I in ${REPOS}; do\n                REPO=$(echo ${I} | ${AWKBINARY} -F= '{print $1}')\n                GPGSIGNED=$(echo ${I} | ${AWKBINARY} -F= '{print $2}')\n                if [ \"${GPGSIGNED}\" = \"False\" ]; then\n                    LogText \"Result: software repository '${REPO}' is NOT signed\"\n                    Report \"software_repository_unsigned[]=${REPO}\"\n                    AddHP 3 4\n                elif [ \"${GPGSIGNED}\" = \"True\" ]; then\n                    LogText \"Result: software repository '${REPO}' is signed\"\n                    AddHP 4 4\n                else\n                    LogText \"Result: unknown status for repository (data: ${I})\"\n                fi\n            done\n        fi\n        FOUND=0\n        FileExists ${ROOTDIR}etc/yum.conf\n        if [ ${FILE_FOUND} -eq 1 ]; then\n            if SearchItem \"^gpgenabled\\s*=\\s*1$\" \"${ROOTDIR}etc/yum.conf\"; then FOUND=1; fi\n            if SearchItem \"^gpgcheck\\s*=\\s*1$\" \"${ROOTDIR}etc/yum.conf\"; then FOUND=1; fi\n            if [ ${FOUND} -eq 1 ]; then\n                LogText \"Result: GPG check is enabled\"\n                Display --indent 2 --text \"- Checking GPG checks (yum.conf)\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 3 3\n            else\n                Display --indent 2 --text \"- Checking GPG checks (yum.conf)\" --result \"${STATUS_DISABLED}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"No GPG signing option found in yum.conf\"\n                AddHP 2 3\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7388\n    # Description : Check security repository in Debian/Ubuntu apt sources.list file\n    PREQS_MET=\"NO\"\n    if [ -f ${ROOTDIR}etc/apt/sources.list -a -d ${ROOTDIR}etc/apt/sources.list.d ]; then\n        case \"${LINUX_VERSION}\" in\n            \"Debian\" | \"Linux Mint\" | \"Ubuntu\" | \"Pop!_OS\")\n                # Todo: PureOS (not rolling) has security repositories\n                # Todo: Debian sid does not have a security repository.\n                PREQS_MET=\"YES\"\n            ;;\n            *)\n                LogText \"Skipping test, although sources.list or sources.list.d exists. This specific OS version most likely has no security repository\"\n            ;;\n        esac\n    fi\n    Register --test-no PKGS-7388 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check security repository in apt sources.list file\"\n    if [ $SKIPTEST -eq 0 ]; then\n        FOUND=0\n        if [ ${OPTION_DEBIAN_SKIP_SECURITY_REPOSITORY} -eq 0 ]; then\n            if [ -f ${ROOTDIR}etc/apt/sources.list ]; then\n                LogText \"Searching for security.debian.org/security.ubuntu.com or security repositories in /etc/apt/sources.list file\"\n                FIND=$(${GREPBINARY} -E \"security.debian.org|security.ubuntu.com|security/? \" ${ROOTDIR}etc/apt/sources.list | ${GREPBINARY} -v '#' | ${SEDBINARY} 's/ /!space!/g')\n                if [ -n \"${FIND}\" ]; then\n                    FOUND=1\n                    Display --indent 2 --text \"- Checking security repository in sources.list file\" --result \"${STATUS_OK}\" --color GREEN\n                    LogText \"Result: Found security repository in ${ROOTDIR}etc/apt/sources.list\"\n                    for REPO in ${FIND}; do\n                        REPO=$(echo ${REPO} | ${SEDBINARY} 's/!space!/ /g')\n                        LogText \"Output: ${REPO}\"\n                    done\n                fi\n            fi\n            if [ -d /etc/apt/sources.list.d ]; then\n                LogText \"Searching for security.debian.org/security.ubuntu.com or security repositories in /etc/apt/sources.list.d directory\"\n                FIND=$(${GREPBINARY} -E -r \"security.debian.org|security.ubuntu.com|security/? \" /etc/apt/sources.list.d | ${GREPBINARY} -v '#' | ${SEDBINARY} 's/ /!space!/g')\n                if [ -n \"${FIND}\" ]; then\n                    FOUND=1\n                    Display --indent 2 --text \"- Checking security repository in sources.list.d directory\" --result \"${STATUS_OK}\" --color GREEN\n                    LogText \"Result: Found security repository in one or more files in directory /etc/apt/sources.list.d\"\n                    for REPO in ${FIND}; do\n                        REPO=$(echo ${REPO} | ${SEDBINARY} 's/!space!/ /g')\n                        LogText \"Output: ${REPO}\"\n                    done\n                fi\n            fi\n            if [ ${FOUND} -eq 1 ]; then\n                LogText \"Result: security repository was found\"\n                AddHP 3 3\n            else\n                Display --indent 2 --text \"- Checking security repository in sources.list file or directory\" --result \"${STATUS_WARNING}\" --color RED\n                ReportWarning \"${TEST_NO}\" \"Can't find any security repository in /etc/apt/sources.list or sources.list.d directory\"\n                AddHP 0 3\n            fi\n        else\n            LogText \"Skipped as option is set to ignore security repository\"\n        fi\n        unset FIND FOUND REPO\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7390\n    # Description : Check Ubuntu database consistency\n    if ([ \"${LINUX_VERSION}\" = \"Debian\" ] || [ \"${LINUX_VERSION}\" = \"Ubuntu\" ] ||\n           [ \"${LINUX_VERSION_LIKE}\" = \"Debian\" ] ||  [ \"${LINUX_VERSION_LIKE}\" = \"Ubuntu\" ]) && [ -x \"${ROOTDIR}usr/bin/apt-get\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    Register --test-no PKGS-7390 --os Linux --preqs-met ${PREQS_MET} --root-only YES --weight L --network NO --category security --description \"Check Ubuntu database consistency\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Package database consistency by running apt-get check\"\n        FIND=$(${ROOTDIR}usr/bin/apt-get -q=2 check 2> /dev/null; echo $?)\n        if [ \"${FIND}\" = \"0\" ]; then\n            Display --indent 2 --text \"- Checking APT package database\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: package database seems to be consistent.\"\n        else\n            LogText \"Result: package database is most likely NOT consistent\"\n            Display --indent 2 --text \"- Checking APT package database\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"apt-get check returned a non successful exit code.\"\n            ReportSuggestion \"${TEST_NO}\" \"Run apt-get to perform a manual package database consistency check.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7392\n    # Description : Check Debian/Ubuntu vulnerable packages\n    # Note        : Skip for zypper-based systems\n    if [ -x ${ROOTDIR}usr/bin/apt-get -a -z \"${ZYPPERBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7392 --os Linux --preqs-met ${PREQS_MET} --root-only YES --weight L --network YES --category security --description \"Check for Debian/Ubuntu security updates\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        VULNERABLE_PACKAGES_FOUND=0\n        SCAN_PERFORMED=0\n        # If apt-get is installed, then it's a reasonable option for a Package Audit tool\n        # If apt-check exists, it will be preferred and will overwrite the PACKAGE_AUDIT_TOOL setting\n        PACKAGE_AUDIT_TOOL=\"apt-get\"\n        PACKAGE_AUDIT_TOOL_FOUND=1\n        # Update the repository, outdated repositories don't give much information\n        if [ ${REFRESH_REPOSITORIES} -eq 1 ]; then\n            LogText \"Action: updating package repository with apt-get\"\n            ${ROOTDIR}usr/bin/apt-get -q=2 update\n            LogText \"Result: apt-get finished\"\n        else\n            LogText \"Result: using a possibly outdated repository, as updating is disabled via configuration\"\n        fi\n        LogText \"Test: Checking if ${ROOTDIR}usr/lib/update-notifier/apt-check exists\"\n        if [ -x ${ROOTDIR}usr/lib/update-notifier/apt-check ]; then\n            PACKAGE_AUDIT_TOOL=\"apt-check\"\n            LogText \"Result: found ${ROOTDIR}usr/lib/update-notifier/apt-check\"\n            LogText \"Test: checking if any of the updates contain security updates\"\n            # apt-check binary is a script and translated. Do not search for normal text strings, but use numbered output only\n            # We search for the lines that start with a number, as on Ubuntu 24.04 an error can happen:\n            # Warning: W:Unable to read /var/lib/ubuntu-advantage/apt-esm/etc/apt/apt.conf.d/ - DirectoryExists (2: No such file or directory)\n            FIND=$(${ROOTDIR}usr/lib/update-notifier/apt-check 2>&1 | ${GREPBINARY} '^[0-9]' | ${AWKBINARY} -F\\; '{ print $2 }')\n            # Check if we get the proper line back and amount of security patches available\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: did not find security updates line\"\n                ReportSuggestion \"${TEST_NO}\" \"Check if system is up-to-date, security updates test (apt-check) gives an unexpected result\"\n                ReportException \"${TEST_NO}:1\" \"Apt-check did not provide any result\"\n            else\n                if [ \"${FIND}\" = \"0\" ]; then\n                    LogText \"Result: no vulnerable packages found via apt-check\"\n                    SCAN_PERFORMED=1\n                else\n                    VULNERABLE_PACKAGES_FOUND=1\n                    SCAN_PERFORMED=1\n                    LogText \"Result: found ${FIND} security updates via apt-check\"\n                    AddHP 0 25\n                fi\n            fi\n        else\n            LogText \"Result: apt-check (update-notifier-common) not found\"\n        fi\n\n        # Trying also with apt-get directly (does not always work, as updates are distributed on both -security and -updates)\n        # Show packages which would be upgraded and match 'security' in repository name\n        FIND=$(${ROOTDIR}usr/bin/apt-get --dry-run --show-upgraded upgrade 2> /dev/null | ${GREPBINARY} '-security' | ${GREPBINARY} \"^Inst\" | ${CUTBINARY} -d ' ' -f2 | ${SORTBINARY} -u)\n        if [ -n \"${FIND}\" ]; then\n            VULNERABLE_PACKAGES_FOUND=1\n            SCAN_PERFORMED=1\n            LogText \"Result: found vulnerable package(s) via apt-get (-security channel)\"\n            PACKAGE_AUDIT_TOOL=\"apt-get\"\n            PACKAGE_AUDIT_TOOL_FOUND=1\n            for PKG in ${FIND}; do\n                LogText \"Found vulnerable package: ${PKG}\"\n                Report \"vulnerable_package[]=${PKG}\"\n            done\n        fi\n        if [ ${SCAN_PERFORMED} -eq 1 ]; then\n            if [ ${VULNERABLE_PACKAGES_FOUND} -eq 1 ]; then\n                ReportWarning \"${TEST_NO}\" \"Found one or more vulnerable packages.\"\n                ReportSuggestion \"${TEST_NO}\" \"Update your system with apt-get update, apt-get upgrade, apt-get dist-upgrade and/or unattended-upgrades\"\n                Display --indent 2 --text \"- Checking vulnerable packages\" --result \"${STATUS_WARNING}\" --color RED\n            else\n                Display --indent 2 --text \"- Checking vulnerable packages\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: no vulnerable packages found\"\n            fi\n        else\n            Display --indent 2 --text \"- Checking vulnerable packages (apt-get only)\" --result \"${STATUS_DONE}\" --color GREEN\n            LogText \"Result: test not fully executed (missing apt-check output)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7393\n    # Description : Check Gentoo vulnerable packages\n    if [ -x ${ROOTDIR}usr/bin/emerge-webrsync ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PKGS-7393 --preqs-met ${PREQS_MET} --weight L --network YES --category security --description \"Check for Gentoo vulnerable packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        VULNERABLE_PACKAGES_FOUND=0\n        SCAN_PERFORMED=0\n        # Update portage.\n        # Multiple ways to do this.  Some require extra packages to be installed,\n        # others require potential firewall ports to be open, outbound.  This is the\n        # \"most friendly\" way.\n        if [ ${REFRESH_REPOSITORIES} -eq 1 ]; then\n            LogText \"Action: updating portage with emerge-webrsync\"\n            ${ROOTDIR}usr/bin/emerge-webrsync --quiet 2> /dev/null\n            LogText \"Result: emerge-webrsync finished\"\n        else\n            LogText \"Result: using a possibly outdated repository, as updating is disabled\"\n        fi\n        LogText \"Test: checking if ${ROOTDIR}usr/bin/glsa-check exists\"\n        if [ -x ${ROOTDIR}usr/bin/glsa-check ]; then\n            PACKAGE_AUDIT_TOOL_FOUND=1\n            PACKAGE_AUDIT_TOOL=\"glsa-check\"\n            LogText \"Result: found ${ROOTDIR}usr/bin/glsa-check\"\n            LogText \"Test: checking if there are any vulnerable packages\"\n            # glsa-check reports the GLSA date/ID string, not the vulnerable package.\n            FIND=$(${ROOTDIR}usr/bin/glsa-check -t all 2>&1 | ${GREPBINARY} -v \"This system is affected by the following GLSAs:\" | ${GREPBINARY} -v \"This system is not affected by any of the listed GLSAs\" | ${WCBINARY} -l)\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: unexpected result: wc should report 0 if no vulnerable packages are found.\"\n                LogText \"Notes: Check if system is up-to-date, security updates check (glsa-check) gives and unexpected result\"\n                ReportException \"${TEST_NO}:1\" \"glsa-check did not provide any result, which is unexpected\"\n            else\n                if [ \"${FIND}\" = \"0\" ]; then\n                    LogText \"Result; no vulnerable packages found via glsa-check\"\n                    Display --indent 2 --text \"- Checking vulnerable packages (glsa-check)\" --result \"${STATUS_OK}\" --color GREEN\n                else\n                    VULNERABLE_PACKAGES_FOUND=1\n                    Display --indent 2 --text \"- Checking vulnerable packages (glsa-check)\" --result \"${STATUS_FOUND}\" --color RED\n                    LogText \"Result: found ${FIND} security updates with glsa-check\"\n                    ReportWarning \"${TEST_NO}\" \"Found ${FIND} security update(s) with glsa-check.\"\n                    LogText \"Notes: Run 'glsa-check -t all' to see which GLSA(s) were identified.\"\n                    AddHP 0 25\n                fi\n            fi\n        else\n            LogText \"Result: glsa-check tool not found\"\n            ReportSuggestion \"${TEST_NO}\" \"Use Emerge to install the gentoolkit package, which includes glsa-check tool for additional security checks.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7394\n    # Description : Check Ubuntu upgradeable packages\n    if ([ \"${LINUX_VERSION}\" = \"Debian\" ] || [ \"${LINUX_VERSION}\" = \"Ubuntu\" ] ||\n           [ \"${LINUX_VERSION_LIKE}\" = \"Debian\" ] ||  [ \"${LINUX_VERSION_LIKE}\" = \"Ubuntu\" ]) && [ -x \"${ROOTDIR}usr/bin/apt-get\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    Register --test-no PKGS-7394 --os Linux --preqs-met ${PREQS_MET} --weight L --network YES --category security --description \"Check for Ubuntu updates\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking ${ROOTDIR}usr/bin/apt-show-versions\"\n        if [ -x ${ROOTDIR}usr/bin/apt-show-versions ]; then\n            LogText \"Result: found ${ROOTDIR}usr/bin/apt-show-versions\"\n            LogText \"Test: Checking packages which can be upgraded via apt-show-versions\"\n            FIND=$(${ROOTDIR}usr/bin/apt-show-versions -u | ${SEDBINARY} 's/ /!space!/g')\n            if [ -z \"${FIND}\" ]; then\n                LogText \"Result: no packages found which can be upgraded\"\n                Display --indent 2 --text \"- Checking upgradeable packages\" --result \"${STATUS_NONE}\" --color GREEN\n                AddHP 3 3\n            else\n                LogText \"Result: found one or more packages which can be upgraded\"\n                Display --indent 2 --text \"- Checking upgradeable packages\" --result \"${STATUS_FOUND}\" --color YELLOW\n                # output: program/repository upgradeable from version X to Y\n                for ITEM in ${FIND}; do\n                    ITEM=$(echo ${ITEM} | ${SEDBINARY} 's/!space!/ /g')\n                    LogText \"${ITEM}\"\n                done\n            fi\n        else\n            LogText \"Result: ${ROOTDIR}usr/bin/apt-show-versions not found\"\n            Display --indent 2 --text \"- Checking upgradeable packages\" --result \"${STATUS_SKIPPED}\" --color WHITE\n            ReportSuggestion \"${TEST_NO}\" \"Install package apt-show-versions for patch management purposes\"\n        fi\n    fi\n\n#\n#################################################################################\n#\n    # Test        : PKGS-7395\n    # Description : Check Alpine upgradeable packages\n    if [ \"${LINUX_VERSION}\" = \"Alpine Linux\" ]  && [ -x \"${ROOTDIR}sbin/apk\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    Register --test-no PKGS-7395 --os Linux --preqs-met ${PREQS_MET} --weight L --network YES --category security --description \"Check for Alpine updates\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${REFRESH_REPOSITORIES} -eq 1 ]; then\n            LogText \"Action: updating package repository with apk\"\n            ${ROOTDIR}sbin/apk update\n            LogText \"Result: apk finished\"\n        else\n            LogText \"Result: using a possibly outdated repository, as updating is disabled via configuration\"\n        fi\n        LogText \"Test: Checking packages which can be upgraded via apk version -l '<'\"\n        FIND=$(${ROOTDIR}sbin/apk version -l '<' | ${GREPBINARY} '<' | ${SEDBINARY} 's/\\s\\+<\\s/</g')\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: no packages found which can be upgraded\"\n            Display --indent 2 --text \"- Checking upgradeable packages\" --result \"${STATUS_NONE}\" --color GREEN\n            AddHP 3 3\n        else\n            LogText \"Result: found one or more packages which can be upgraded\"\n            Display --indent 2 --text \"- Checking upgradeable packages\" --result \"${STATUS_FOUND}\" --color YELLOW\n            for ITEM in ${FIND}; do\n                ITEM=$(echo ${ITEM} | ${SEDBINARY}  -r -e 's/([a-z,A-Z,0-9,_,-,.]{1,250})-([a-z,A-Z,0-9,.]+-r[a-z,A-Z,0-9]+)<([a-z,A-Z,0-9,-,.]+)/\\1 from \\2 to \\3/')\n                LogText \"${ITEM}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7398\n    # Description : Check package audit tool\n    Register --test-no PKGS-7398 --weight L --network YES --category security --description \"Check for package audit tool\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking for package audit tool\"\n        if [ ${PACKAGE_AUDIT_TOOL_FOUND} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking package audit tool\" --result \"${STATUS_NONE}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Install a package audit tool to determine vulnerable packages\"\n            LogText \"Result: no package audit tool found\"\n        else\n            Display --indent 2 --text \"- Checking package audit tool\" --result \"${STATUS_INSTALLED}\" --color GREEN\n            Display --indent 4 --text \"Found: ${PACKAGE_AUDIT_TOOL}\"\n            LogText \"Result: found package audit tool: ${PACKAGE_AUDIT_TOOL}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Description : HP-UX packages\n    # Notes       : swlist -l fileset (|${GREPBINARY} patch) / print_manifest\n#\n#################################################################################\n#\n    # Description : AIX patches\n    # Notes       : ${ROOTDIR}usr/sbin/instfix -c -i | ${CUTBINARY} -d\":\" -f1\n#\n#################################################################################\n#\n    # Test        : PKGS-7410\n    # Description : Count number of installed kernel packages\n    Register --test-no PKGS-7410 --weight L --network NO --category security --description \"Count installed kernel packages\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        KERNELS=0\n        TESTED=0\n        LogText \"Test: Checking how many kernel packages are installed\"\n\n        if [ \"${DPKGBINARY}\" ]; then\n            TESTED=1\n            KERNEL_PKG_NAMES=\"linux-image-[0-9]|raspberrypi-kernel|pve-kernel-[0-9]|linux-odroid-5422\"\n            KERNELS=$(${DPKGBINARY} -l 2> /dev/null | ${GREPBINARY} -E \"${KERNEL_PKG_NAMES}\" | ${GREPBINARY} -v ^rc | ${WCBINARY} -l)\n            if [ ${KERNELS} -eq 0 ]; then\n                LogText \"Result: found no kernels from dpkg -l output, which is unexpected\"\n            elif [ ${KERNELS} -gt 5 ]; then\n                LogText \"Result: found more than 5 kernel packages on the system, which might indicate lack of regular cleanups\"\n                ReportSuggestion \"${TEST_NO}\" \"Remove any unneeded kernel packages\" \"${KERNELS} kernels\" \"text:validate dpkg -l output and perform cleanup with apt autoremove\"\n            else\n                LogText \"Result: found ${KERNELS} kernel packages on the system, which is fine\"\n            fi\n        fi\n        if [ \"${RPMBINARY}\" ]; then\n            TESTED=1\n            KERNELS=$(${RPMBINARY} -q kernel 2> /dev/null | ${WCBINARY} -l)\n            if [ ${KERNELS} -eq 0 ]; then\n                LogText \"Result: found no kernels from rpm -q kernel output, which is unexpected\"\n            elif [ ${KERNELS} -gt 5 ]; then\n                LogText \"Result: found more than 5 kernel packages on the system, which might indicate lack of regular cleanups\"\n                ReportSuggestion \"${TEST_NO}\" \"Remove any unneeded kernel packages with package-cleanup utility (--old-kernels)\"\n            else\n                LogText \"Result: found ${KERNELS} kernel packages on the system, which is fine\"\n            fi\n        fi\n\n        if [ \"${ZYPPERBINARY}\" ]; then\n            TESTED=1\n            KERNELS=$(${ZYPPERBINARY} --non-interactive -n se --type package --match-exact --installed-only \"kernel-default\" 2> /dev/null | ${GREPBINARY} \"kernel-default\" | ${WCBINARY} -l)\n            if [ ${KERNELS} -eq 0 ]; then\n                LogText \"Result: found no kernels from zypper output, which is unexpected.\"\n                ReportException \"${TEST_NO}\" \"Could not find any kernel packages via package manager. Maybe using a different kernel package?\"\n            elif [ ${KERNELS} -gt 3 ]; then\n                LogText \"Result: found more than 5 kernel packages on the system, which might indicate lack of regular cleanups\"\n                ReportSuggestion \"${TEST_NO}\" \"Remove any unneeded kernel packages\"\n            else\n                LogText \"Result: found ${KERNELS} kernel packages on the system, which is fine\"\n            fi\n        fi\n\n        if [ ${KERNELS} -eq 0 -a ${TESTED} -eq 1 ]; then\n            # Only report exception if there are kernels actually there. For example, LXC use the kernel of host system\n            case \"${OS}\" in\n                \"Linux\")\n                    case \"${CONTAINER_TYPE}\" in\n                        \"LXC\")\n                            LogText \"Info: LXC shares the kernel with host, so skipping further testing\"\n                        ;;\n                        *)\n                            if [ -d \"${ROOTDIR}boot\" ]; then\n                                if [ -z \"$(${FINDBINARY} /boot -maxdepth 1 -type f -name 'vmlinuz*' -print -quit)\" ]; then\n                                    ReportException \"${TEST_NO}\" \"Could not find any kernel packages via package manager\"\n                                fi\n                            fi\n                        ;;\n                    esac\n                ;;\n                *)\n                    ReportException \"${TEST_NO}\" \"Could not find any kernel packages via package manager\"\n                ;;\n            esac\n        fi\n\n        Report \"installed_kernel_packages=${KERNELS}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PKGS-7420\n    # Description : Detect toolkit to automatically download and apply upgrades\n    Register --test-no PKGS-7420 --weight L --network NO --category security --description \"Detect toolkit to automatically download and apply upgrades\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        UNATTENDED_UPGRADES_TOOLKIT=0\n        UNATTENDED_UPGRADES_TOOL=\"\"\n        UNATTENDED_UPGRADES_OPTION_AVAILABLE=0\n\n        case \"${OS}\" in\n            \"Linux\")\n                for DIST in CentOS Debian Fedora RHEL Ubuntu; do\n                    if [ \"${LINUX_VERSION}\" = \"${DIST}\" ] || [ \"${LINUX_VERSION_LIKE}\" = \"${DIST}\" ]; then\n                        UNATTENDED_UPGRADES_OPTION_AVAILABLE=1\n                    fi\n                done\n\n                if [ ${UNATTENDED_UPGRADES_OPTION_AVAILABLE} -eq 1 ]; then\n                    # Test available tools for Linux\n                    if [ -f \"${ROOTDIR}bin/auter\" ]; then\n                        UNATTENDED_UPGRADES_TOOL=\"auter\"\n                        UNATTENDED_UPGRADES_TOOLKIT=1\n                        LogText \"Result: found ${UNATTENDED_UPGRADES_TOOL}\"\n                        Report \"unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}\"\n                    fi\n                    if [ -f \"${ROOTDIR}sbin/yum-cron\" ]; then\n                        UNATTENDED_UPGRADES_TOOL=\"yum-cron\"\n                        UNATTENDED_UPGRADES_TOOLKIT=1\n                        LogText \"Result: found ${UNATTENDED_UPGRADES_TOOL}\"\n                        Report \"unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}\"\n                    fi\n                    if [ -f \"${ROOTDIR}usr/bin/dnf-automatic\" ]; then\n                        UNATTENDED_UPGRADES_TOOL=\"dnf-automatic\"\n                        UNATTENDED_UPGRADES_TOOLKIT=1\n                        LogText \"Result: found ${UNATTENDED_UPGRADES_TOOL}\"\n                        Report \"unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}\"\n                    fi\n                    if [ -f \"${ROOTDIR}usr/bin/unattended-upgrade\" ]; then\n                        UNATTENDED_UPGRADES_TOOL=\"unattended-upgrade\"\n                        UNATTENDED_UPGRADES_TOOLKIT=1\n                        LogText \"Result: found ${UNATTENDED_UPGRADES_TOOL}\"\n                        Report \"unattended_upgrade_tool[]=${UNATTENDED_UPGRADES_TOOL}\"\n                    fi\n                fi\n            ;;\n        esac\n\n        if [ ${UNATTENDED_UPGRADES_OPTION_AVAILABLE} -eq 1 ]; then\n            if [ ${UNATTENDED_UPGRADES_TOOLKIT} -eq 1 ]; then\n                AddHP 5 5\n                Display --indent 2 --text \"- Toolkit for automatic upgrades (${UNATTENDED_UPGRADES_TOOL})\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                AddHP 1 5\n                Display --indent 2 --text \"- Toolkit for automatic upgrades\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n                LogText \"Result: no toolkit for automatic updates discovered\"\n                ReportSuggestion \"${TEST_NO}\" \"Consider using a tool to automatically apply upgrades\"\n            fi\n        fi\n\n        Report \"unattended_upgrade_option_available=${UNATTENDED_UPGRADES_OPTION_AVAILABLE}\"\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_printers_spoolers",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Printers and spools\n#\n#################################################################################\n#\n    CUPSD_CONFIG_LOCS=\"${ROOTDIR}etc/cups ${ROOTDIR}usr/local/etc/cups ${ROOTDIR}private/etc/cups\"\n    CUPSD_CONFIG_FILE=\"\"\n    CUPSD_RUNNING=0\n    CUPSD_FOUND=0\n    LPD_RUNNING=0\n    PRINTING_DAEMON=\"\"\n    QDAEMON_CONFIG_ENABLED=0\n    QDAEMON_CONFIG_FILE=\"\"\n    QDAEMON_RUNNING=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_PRINTERS_AND_SPOOLS}\"\n#\n#################################################################################\n#\n    # Test        : PRNT-2302\n    # Description : Check printcap file consistency\n    Register --test-no PRNT-2302 --os FreeBSD --weight L --network NO --category security --description \"Check for printcap consistency\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching /usr/sbin/chkprintcap\"\n        if [ ! -f ${ROOTDIR}usr/sbin/chkprintcap ]; then\n            Display --indent 2 --text \"- Checking chkprintcap\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: ${ROOTDIR}usr/sbin/chkprintcap NOT found, test skipped\"\n        else\n            LogText \"Result: ${ROOTDIR}usr/sbin/chkprintcap found\"\n            FIND=$(${ROOTDIR}usr/sbin/chkprintcap > /dev/null ; echo $?)\n            # Only an exit code of zero should come back. Use string instead of integer, due unexpected trash\n            if [ \"${FIND}\" = \"0\" ]; then\n                Display --indent 2 --text \"- Integrity check of printcap file\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: chkprintcap did NOT gave any warnings\"\n            else\n                Display --indent 2 --text \"- Integrity check of printcap file\" --result \"${STATUS_WARNING}\" --color RED\n                ReportSuggestion \"${TEST_NO}\" \"Run chkprintcap manually to test printcap file\"\n                LogText \"Output from chkprintcap: ${FIND}\"\n                LogText \"Run chkprintcap and check the ${ROOTDIR}etc/printcap file\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2304\n    # Description : Check cupsd status\n    Register --test-no PRNT-2304 --weight L --network NO --category security --description \"Check cupsd status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking cupsd status\"\n        if IsRunning \"cupsd\"; then\n            Display --indent 2 --text \"- Checking cups daemon\" --result \"${STATUS_RUNNING}\" --color GREEN\n            LogText \"Result: cups daemon running\"\n            CUPSD_RUNNING=1; PRINTING_DAEMON=\"cups\"\n        else\n            Display --indent 2 --text \"- Checking cups daemon\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            LogText \"Result: cups daemon not running, cups daemon tests skipped\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2306\n    # Description : Check CUPSd configuration file\n    if [ ${CUPSD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PRNT-2306 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check CUPSd configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching cupsd configuration file\"\n        for DIR in ${CUPSD_CONFIG_LOCS}; do\n            if [ -f ${DIR}/cupsd.conf ]; then\n                if FileIsReadable ${DIR}/cupsd.conf; then\n                    CUPSD_CONFIG_FILE=\"${DIR}/cupsd.conf\"\n                    LogText \"Result: found ${CUPSD_CONFIG_FILE}\"\n                fi\n            fi\n        done\n        if HasData \"${CUPSD_CONFIG_FILE}\"; then\n            Display --indent 2 --text \"- Checking CUPS configuration file\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: configuration file found (${CUPSD_CONFIG_FILE})\"\n            CUPSD_FOUND=1\n        else\n            Display --indent 2 --text \"- Checking CUPS configuration file\" --result \"${STATUS_NOT_FOUND}\" --color RED\n            LogText \"Result: configuration file not found\"\n            LogText \"Development: no CUPS configuration file found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2307\n    # Description : Check CUPSd configuration file permissions\n    # TODO        : Add function\n    if [ ${CUPSD_FOUND} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PRNT-2307 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check CUPSd configuration file permissions\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking CUPS configuration file permissions\"\n        FIND=$(${LSBINARY} -l ${CUPSD_CONFIG_FILE} | ${CUTBINARY} -c 2-10)\n        LogText \"Result: found ${FIND}\"\n        case \"${FIND}\" in\n            r[w-]-[r-][w-]---- )\n                Display --indent 4 --text \"- File permissions\" --result \"${STATUS_OK}\" --color GREEN\n                AddHP 1 1\n                ;;\n            * )\n                Display --indent 4 --text \"- File permissions\" --result \"${STATUS_WARNING}\" --color RED\n                ReportSuggestion \"${TEST_NO}\" \"Access to CUPS configuration could be more strict.\"\n                AddHP 1 2\n                ;;\n        esac\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2308\n    # Description : Check CUPS daemon network configuration\n    # Notes       : Listen and SSLListen can be used\n    if [ ${CUPSD_FOUND} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PRNT-2308 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check CUPSd network configuration\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        PORT_FOUND=0\n\n        LogText \"Test: Checking CUPS daemon listening network addresses\"\n\n        # Search for Port statement\n        FIND=$(${GREPBINARY} -E \"^Port 631\" ${CUPSD_CONFIG_FILE})\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found CUPS listening on port 631 (most likely all interfaces)\"\n            PORT_FOUND=1\n        fi\n\n        # Checking network addresses\n        FIND=$(${GREPBINARY} -E \"^(SSL)?Listen\" ${CUPSD_CONFIG_FILE} | ${GREPBINARY} -v \"/\" | ${AWKBINARY} '{ print $2 }')\n        COUNT=0\n        for ITEM in ${FIND}; do\n            LogText \"Result: found network address: ${ITEM}\"\n            COUNT=$((COUNT + 1))\n            FOUND=1\n        done\n\n        # Check if daemon might be running on localhost\n        if [ ${FOUND} -eq 0 -a ${PORT_FOUND} -eq 0 ]; then\n            LogText \"Result: CUPS does not look to be listening on a network port\"\n        elif [ ${COUNT} -eq 1 -a ${PORT_FOUND} -eq 0 ]; then\n            if [ \"${FIND}\" = \"localhost:631\" -o \"${FIND}\" = \"127.0.0.1:631\" ]; then\n                LogText \"Result: CUPS daemon only running on localhost\"\n                AddHP 2 2\n            else\n                LogText \"Result: CUPS daemon running on one or more interfaces (not limited to localhost)\"\n                ReportSuggestion \"${TEST_NO}\" \"Check CUPS configuration if it really needs to listen on the network\"\n                AddHP 1 2\n            fi\n        else\n            LogText \"Result: CUPS daemon is running on several network addresses\"\n            ReportSuggestion \"${TEST_NO}\" \"Check CUPS configuration if it really needs to run on several network addresses\"\n            AddHP 1 2\n        fi\n\n        # Checking sockets\n        LogText \"Test: Checking cups daemon listening sockets\"\n        FIND=$(${GREPBINARY} \"^Listen\" ${CUPSD_CONFIG_FILE} | ${GREPBINARY} \"/\" | ${AWKBINARY} '{ print $2 }')\n        for ITEM in ${FIND}; do\n            LogText \"Found socket address: ${ITEM}\"\n            COUNT=$((COUNT + 1))\n        done\n\n        if [ ${COUNT} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking CUPS addresses/sockets\" --result \"${STATUS_NONE}\" --color WHITE\n            LogText \"Result: no addresses found on which CUPS daemon is listening\"\n        else\n            Display --indent 2 --text \"- Checking CUPS addresses/sockets\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: CUPS daemon is listening on network/socket\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2314\n    # Description : Check lpd status\n    Register --test-no PRNT-2314 --weight L --network NO --category security --description \"Check lpd status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking lpd status\"\n        if IsRunning \"lpd\"; then\n            Display --indent 2 --text \"- Checking lp daemon\" --result \"${STATUS_RUNNING}\" --color GREEN\n            LogText \"Result: lp daemon running\"\n            LPD_RUNNING=1; PRINTING_DAEMON=\"lp\"\n        else\n            Display --indent 2 --text \"- Checking lp daemon\" --result \"${STATUS_NOT_RUNNING}\" --color WHITE\n            LogText \"Result: lp daemon not running\"\n            AddHP 4 4\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2316\n    # Description : Check /etc/qconfig file\n    Register --test-no PRNT-2316 --os AIX --weight L --network NO --category security --description \"Checking /etc/qconfig file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking ${ROOTDIR}etc/qconfig\"\n        QDAEMON_CONFIG_FILE=\"${ROOTDIR}etc/qconfig\"\n        FileIsReadable ${QDAEMON_CONFIG_FILE}\n        if [ ${CANREAD} -eq 1 ]; then\n            FIND=$(${GREPBINARY} -v \"^\\*\" ${QDAEMON_CONFIG_FILE} | ${GREPBINARY} -E \"backend|device\")\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: printers are defined in ${QDAEMON_CONFIG_FILE}\"\n                Display --indent 2 --text \"- Checking /etc/qconfig file\" --result \"${STATUS_FOUND}\" --color GREEN\n                QDAEMON_CONFIG_ENABLED=1\n            else\n                LogText \"Result: ${QDAEMON_CONFIG_FILE} is empty. No printers are defined\"\n                Display --indent 2 --text \"- Checking /etc/qconfig file\" --result EMPTY --color WHITE\n            fi\n        else\n            LogText \"Result: Can not read ${QDAEMON_CONFIG_FILE} (no permission)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2418\n    # Description : Check qdaemon printer spooler status\n    Register --test-no PRNT-2418 --os AIX --weight L --network NO --category security --description \"Checking qdaemon printer spooler status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking qdaemon status\"\n        if IsRunning \"qdaemon\"; then\n            LogText \"Result: qdaemon daemon running\"\n            Display --indent 2 --text \"- Checking qdaemon daemon\" --result \"${STATUS_RUNNING}\" --color GREEN\n            QDAEMON_RUNNING=1; PRINTING_DAEMON=\"qdaemon\"\n        else\n            if [ ${QDAEMON_CONFIG_ENABLED} -eq 1 ]; then\n                LogText \"Result: qdaemon daemon not running\"\n                Display --indent 2 --text \"- Checking qdaemon daemon\" --result \"${STATUS_NOT_RUNNING}\" --color RED\n                ReportSuggestion \"${TEST_NO}\" \"Activate print spooler daemon (qdaemon) in order to process print jobs\"\n            else\n                LogText \"Result: qdaemon daemon not running\"\n                Display --indent 2 --text \"- Checking qdaemon daemon\" --result \"${STATUS_NOT_RUNNING}\" --color WHITE\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PRNT-2420\n    # Description : Checking old print jobs\n    Register --test-no PRNT-2420 --os AIX --weight L --network NO --category security --description \"Checking old print jobs\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking old print jobs\"\n        DirectoryExists ${ROOTDIR}var/spool/lpd/qdir\n        if [ ${DIRECTORY_FOUND} -eq 1 ]; then\n            FIND=$(find ${ROOTDIR}var/spool/lpd/qdir -type f -mtime +1 2> /dev/null | ${SEDBINARY} 's/ /!space!/g')\n            if HasData \"${FIND}\"; then\n                COUNT=0\n                for ITEM in ${FIND}; do\n                    FILE=$(echo ${ITEM} | ${SEDBINARY} 's/!space!/ /g')\n                    LogText \"Found old print job: ${FILE}\"\n                    COUNT=$((COUNT + 1))\n                done\n                LogText \"Result: Found ${COUNT} old print jobs in /var/spool/lpd/qdir\"\n                Display --indent 4 --text \"- Checking old print jobs\" --result \"${STATUS_FOUND}\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Check old print jobs in /var/spool/lpd/qdir to prevent new jobs from being processed\"\n                LogText \"Risk: Failed or defunct print jobs can occupy a lot of space and in some cases, prevent new jobs from being processed\"\n            else\n                LogText \"Result: Old print jobs not found in /var/spool/lpd/qdir\"\n                Display --indent 4 --text \"- Checking old print jobs\" --result \"${STATUS_NONE}\" --color GREEN\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n\nif [ -n \"${PRINTING_DAEMON}\" ]; then Report \"printing_daemon=${PRINTING_DAEMON}\"; fi\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_scheduling",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Scheduled tasks\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_SCHEDULED_TASKS}\"\n#\n#################################################################################\n#\n    ATD_RUNNING=0\n    CROND_RUNNING=0\n#\n#################################################################################\n#\n    # Test        : SCHD-7702\n    # Description : Check cron daemon\n    Register --test-no SCHD-7702 --weight L --network NO --category security --description \"Check status of cron daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${PSBINARY} aux | ${GREPBINARY} -E \"( cron$|/cron(d)? )\")\n        if IsEmpty \"${FIND}\"; then\n            LogText \"Result: no cron daemon found\"\n        else\n            LogText \"Result: cron daemon running\"\n            CROND_RUNNING=1\n            Report \"crond_running=1\"\n            Report \"scheduler[]=crond\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SCHD-7704\n    # Description : Check crontab / cronjobs\n    Register --test-no SCHD-7704 --weight L --network NO --category security --description \"Check crontab/cronjobs\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        BAD_FILE_PERMISSIONS=0\n        BAD_FILE_OWNERSHIP=0\n        FindCronJob() {\n            sCRONJOBS=$(${GREPBINARY} -E '^([0-9*])' $1 | ${TRBINARY} '\\t' ' ' | ${TRBINARY} -s ' ' | ${TRBINARY} ' ' ',' | ${SORTBINARY})\n        }\n\n        CRONTAB_FILE=\"${ROOTDIR}etc/crontab\"\n        if [ -f ${CRONTAB_FILE} ]; then\n            ${GREPBINARY} -E -q -s 'lynis audit system' ${CRONTAB_FILE} && LYNIS_CRONJOB=\"file:/etc/crontab\"\n            if IsWorldWritable ${CRONTAB_FILE}; then LogText \"Result: insecure file permissions for cronjob file ${CRONTAB_FILE}\"; Report \"insecure_fileperms_cronjob[]=${CRONTAB_FILE}\"; BAD_FILE_PERMISSIONS=1; AddHP 0 5; fi\n            if ! IsOwnedByRoot ${CRONTAB_FILE}; then LogText \"Result: incorrect owner found for cronjob file ${CRONTAB_FILE}\"; Report \"bad_fileowner_cronjob[]=${CRONTAB_FILE}\"; BAD_FILE_OWNERSHIP=1; AddHP 0 5; fi\n            FindCronJob ${CRONTAB_FILE}\n            for ITEM in ${sCRONJOBS}; do\n                LogText \"Found cronjob (${CRONTAB_FILE}): ${ITEM}\"\n                Report \"cronjob[]=${ITEM}\"\n            done\n        fi\n\n        CRON_DIRS=\"${ROOTDIR}etc/cron.d\"\n        for DIR in ${CRON_DIRS}; do\n            LogText \"Test: checking directory ${DIR}\"\n            if [ -d ${DIR} ]; then\n                if FileIsReadable ${DIR}; then\n                    LogText \"Result: found directory ${DIR}\"\n                    LogText \"Test: searching files in ${DIR}\"\n                    FIND=$(${FINDBINARY} -L ${DIR} -type f -print | ${GREPBINARY} -v \".placeholder\")\n                    if IsEmpty \"${FIND}\"; then\n                        LogText \"Result: no files found in ${DIR}\"\n                    else\n                        LogText \"Result: found one or more files in ${DIR}. Analyzing files..\"\n                        for FILE in ${FIND}; do\n                            if IsWorldWritable ${FILE}; then LogText \"Result: insecure file permissions for cronjob file ${J}\"; Report \"insecure_fileperms_cronjob[]=${J}\"; BAD_FILE_PERMISSIONS=1; AddHP 0 5; fi\n                            if ! IsOwnedByRoot ${FILE}; then LogText \"Result: incorrect owner found for cronjob file ${J}\"; Report \"bad_fileowner_cronjob[]=${J}\"; BAD_FILE_OWNERSHIP=1; AddHP 0 5; fi\n                            FILENAME=$(echo ${FILE} | ${AWKBINARY} -F/ '{print $NF}')\n                            if [ \"${FILENAME}\" = \"lynis\" ]; then ${GREPBINARY} -E -q -s 'lynis audit system' ${CRONTAB_FILE} && LYNIS_CRONJOB=\"file:${FILE}\"; fi\n                            FindCronJob ${FILE}\n                            if HasData \"${sCRONJOBS}\"; then\n                                for K in ${sCRONJOBS}; do\n                                    LogText \"Result: Found cronjob (${FILE}): ${K}\"\n                                    Report \"cronjob[]=${FILE}\"\n                                done\n                            fi\n                        done\n                        LogText \"Result: done with analyzing files in ${DIR}\"\n                    fi\n                else\n                    LogText \"Result: can not read file or directory ${DIR}\"\n                fi\n            else\n                LogText \"Result: directory ${DIR} does not exist\"\n            fi\n        done\n\n        CRON_DIRS=\"${ROOTDIR}etc/cron.hourly ${ROOTDIR}etc/cron.daily ${ROOTDIR}etc/cron.weekly ${ROOTDIR}etc/cron.monthly\"\n        for I in ${CRON_DIRS}; do\n            LogText \"Test: checking directory ${I}\"\n            if [ -d ${I} ]; then\n                LogText \"Result: found directory ${I}\"\n                if FileIsReadable ${I}; then\n                    LogText \"Test: searching files in ${I}\"\n                    FIND=$(${FINDBINARY} -L ${I} -type f -print 2> /dev/null | ${GREPBINARY} -v \".placeholder\")\n                    if [ -z \"${FIND}\" ]; then\n                        LogText \"Result: no files found in ${I}\"\n                    else\n                        LogText \"Result: found one or more files in ${I}. Analyzing files..\"\n                        for FILE in ${FIND}; do\n                            if IsWorldWritable ${FILE}; then LogText \"Result: insecure file permissions for cronjob file ${FILE}\"; Report \"insecure_fileperms_cronjob[]=${FILE}\"; BAD_FILE_PERMISSIONS=1; AddHP 0 5; fi\n                            if ! IsOwnedByRoot ${FILE}; then LogText \"Result: incorrect owner found for cronjob file ${FILE}\"; Report \"bad_fileowner_cronjob[]=${FILE}\"; BAD_FILE_OWNERSHIP=1; AddHP 0 5; fi\n                            FILENAME=$(echo ${FILE} | ${AWKBINARY} -F/ '{print $NF}')\n                            if [ \"${FILENAME}\" = \"lynis\" ]; then ${GREPBINARY} -E -q -s 'lynis audit system' ${CRONTAB_FILE} && LYNIS_CRONJOB=\"file:${FILE}\"; fi\n                            LogText \"Result: Found cronjob (${I}): ${FILE}\"\n                            Report \"cronjob[]=${FILE}\"\n                        done\n                        LogText \"Result: done with analyzing files in ${I}\"\n                    fi\n                else\n                    LogText \"Result: directory permissions are too strict to enter it (which might be good)\"\n                fi\n            else\n                LogText \"Result: directory ${I} does not exist\"\n            fi\n        done\n\n        # /var/spool/cron/* and /var/spool/cron/crontabs/*\n        # Search only in one tree, to avoid searching the tree twice\n        if [ -d /var/spool/cron/crontabs ]; then\n            FIND=$(${FINDBINARY} /var/spool/cron/crontabs -xdev -type f -print 2> /dev/null)\n            for I in ${FIND}; do\n                if FileIsReadable ${I}; then\n                    ${GREPBINARY} -E -q -s 'lynis audit system' ${I} && LYNIS_CRONJOB=\"file:${I}\"\n                    FindCronJob ${I}\n                    for FILE in ${sCRONJOBS}; do\n                        LogText \"Found cronjob (/var/spool/cron/crontabs): ${I} (${FILE})\"\n                        Report \"cronjob[]=${I}\"\n                    done\n                fi\n            done\n        else\n            if [ -d ${ROOTDIR}var/spool/cron ]; then\n                FIND=$(find ${ROOTDIR}var/spool/cron -type f -print)\n                for I in ${FIND}; do\n                    if FileIsReadable ${I}; then\n                        ${GREPBINARY} -E -q -s 'lynis audit system' ${I} && LYNIS_CRONJOB=\"file:${I}\"\n                        FindCronJob ${I}\n                        for FILE in ${sCRONJOBS}; do\n                            LogText \"Found cronjob in ${ROOTDIR}var/spool/cron: ${I} (${FILE})\"\n                            LogText \"cronjob[]=${I}\"\n                        done\n                    fi\n                done\n            fi\n        fi\n\n        # Anacron\n        if [ \"${OS}\" = \"Linux\" ]; then\n            if [ -f /etc/anacrontab ]; then\n                LogText \"Test: checking anacrontab\"\n                sANACRONJOBS=$(${GREPBINARY} -E '^([0-9@])' /etc/anacrontab | ${TRBINARY} '\\t' ' ' | ${TRBINARY} -s ' ' | ${TRBINARY} ' ' ',' | ${SORTBINARY})\n                if [ -n \"${sANACRONJOBS}\" ]; then\n                    Report \"scheduler[]=anacron\"\n                    for I in ${sANACRONJOBS}; do\n                        LogText \"Found anacron job (/etc/anacrontab): ${I}\"\n                        Report \"cronjob[]=${I}\"\n                    done\n                fi\n            fi\n        fi\n\n        # Show warning when an issue shows up. Even if *both* the permissions and ownership are wrong, just show one (prevent overload of warnings).\n        if [ ${BAD_FILE_PERMISSIONS} -eq 1 ]; then\n            ReportWarning \"${TEST_NO}\" \"Found one or more cronjob files with incorrect file permissions (see log for details)\"\n            Display --indent 2 --text \"- Checking crontab and cronjobs files\" --result \"${STATUS_WARNING}\" --color RED\n        elif [ ${BAD_FILE_OWNERSHIP} -eq 1 ]; then\n            ReportWarning \"${TEST_NO}\" \"Found one or more cronjob files with incorrect ownership (see log for details)\"\n            Display --indent 2 --text \"- Checking crontab and cronjob files\" --result \"${STATUS_WARNING}\" --color RED\n        else\n            Display --indent 2 --text \"- Checking crontab and cronjob files\" --result \"${STATUS_DONE}\" --color GREEN\n        fi\n\n    fi\n#\n#################################################################################\n#\n    # Test        : SCHD-7718\n    # Description : Check atd status\n    Register --test-no SCHD-7718 --weight L --network NO --category security --description \"Check at users\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking atd status\"\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} \"/atd\" | ${GREPBINARY} -v \"grep\")\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: at daemon active\"\n            Display --indent 2 --text \"- Checking atd status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            ATD_RUNNING=1\n            Report \"scheduler[]=atd\"\n        else\n            LogText \"Result: at daemon not active\"\n            if IsVerbose; then Display --indent 2 --text \"- Checking atd status\" --result \"${STATUS_NOT_RUNNING}\" --color WHITE; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SCHD-7720\n    # Description : Check at users\n    # Notes       : if at.allow exists, only users listed can schedule at jobs\n    #               if at.allow does not exist, but at.deny does, everyone\n    #               except the listed ones can schedule jobs. If both can't be\n    #               found, only root can schedule jobs.\n    if [ ${ATD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SCHD-7720 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check at users\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        AT_UNKNOWN=0\n        case ${OS} in\n            FreeBSD)          AT_ALLOW=\"${ROOTDIR}var/at/at.allow\";        AT_DENY=\"${ROOTDIR}var/at/at.deny\"         ;;\n            HPUX)             AT_ALLOW=\"${ROOTDIR}usr/lib/cron/at.allow\";  AT_DENY=\"${ROOTDIR}usr/lib/cron/at.deny\"   ;;\n            Linux)            AT_ALLOW=\"${ROOTDIR}etc/at.allow\";           AT_DENY=\"${ROOTDIR}etc/at.deny\"            ;;\n            OpenBSD)          AT_ALLOW=\"${ROOTDIR}var/cron/at.allow\";      AT_DENY=\"${ROOTDIR}var/cron/at.deny\"       ;;\n            SunOS)            AT_ALLOW=\"${ROOTDIR}etc/cron.d/at.allow\";    AT_DENY=\"${ROOTDIR}etc/cron.d/at.deny\"     ;;\n            *)                AT_UNKNOWN=1; LogText \"Test skipped, files for at unknown\"            ;;\n        esac\n        if [ ${AT_UNKNOWN} -eq 0 ]; then\n            LogText \"Test: checking for file ${AT_ALLOW}\"\n            if [ -f ${AT_ALLOW} ]; then\n                FileIsReadable ${AT_ALLOW}\n                if [ ${CANREAD} -eq 1 ]; then\n                    LogText \"Result: file ${AT_ALLOW} exists, only listed users can schedule at jobs\"\n                    FIND=$(${SORTBINARY} ${AT_ALLOW})\n                    if IsEmpty \"${FIND}\"; then\n                        LogText \"Result: File empty, no users are allowed to schedule at jobs\"\n                    else\n                        for ITEM in ${FIND}; do\n                           LogText \"Allowed at user: ${ITEM}\"\n                        done\n                    fi\n                else\n                    LogText \"Result: can not read ${AT_ALLOW} (no permission)\"\n                fi\n            else\n                LogText \"Result: file ${AT_ALLOW} does not exist\"\n                LogText \"Test: checking for file ${AT_DENY}\"\n                if [ -f ${AT_DENY} ]; then\n                    FileIsReadable ${AT_DENY}\n                    if [ ${CANREAD} -eq 1 ]; then\n                        LogText \"Result: file ${AT_DENY} exists, only non listed users can schedule at jobs\"\n                        FIND=$(${SORTBINARY} ${AT_DENY})\n                        if [ -z \"${FIND}\" ]; then\n                            LogText \"Result: file is empty, no users are denied access to schedule jobs\"\n                        else\n                            for ITEM in ${FIND}; do\n                                LogText \"Denied at user: ${ITEM}\"\n                            done\n                        fi\n                    else\n                        LogText \"Result: can not read ${AT_DENY} (no permission)\"\n                    fi\n                else\n                    LogText \"Result: both ${AT_ALLOW} and ${AT_DENY} do not exist\"\n                    LogText \"Note: only root can schedule at jobs\"\n                    AddHP 1 1\n                fi\n            fi\n            Display --indent 4 --text \"- Checking at users\" --result \"${STATUS_DONE}\" --color GREEN\n        else\n            Display --indent 4 --text \"- Checking at users\" --result \"${STATUS_SKIPPED}\" --color YELLOW\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SCHD-7724\n    # Description : Check scheduled at jobs\n    if [ ${ATD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SCHD-7724 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check at jobs\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check scheduled at jobs\"\n        FIND=$(atq | ${GREPBINARY} -v \"no files in queue\" | ${AWKBINARY} '{gsub(\"\\t\",\" \");print}' | ${SEDBINARY} 's/ /!space!/g')\n        if HasData \"${FIND}\"; then\n            LogText \"Result: found one or more jobs\"\n            for ITEM in ${FIND}; do\n                VALUE=$(echo ${ITEM} | ${SEDBINARY} 's/!space!/ /g')\n                LogText \"Found at job: ${VALUE}\"\n            done\n            Display --indent 4 --text \"- Checking at jobs\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: no pending at jobs\"\n            Display --indent 4 --text \"- Checking at jobs\" --result \"${STATUS_NONE}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n\nif [ -z \"${LYNIS_CRONJOB}\" ]; then\n    LogText \"Result: no scheduled Lynis execution found (e.g. crontab, cronjob)\"\nelse\n    LogText \"Result: found scheduled Lynis execution (${LYNIS_CRONJOB})\"\nfi\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_shells",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Shells\n#\n#################################################################################\n#\n    IDLE_TIMEOUT=0\n    InsertSection \"${SECTION_SHELLS}\"\n#\n#################################################################################\n#\n    # bash\n    # Files (interactive login shells):     /etc/profile $HOME/.bash_profile\n    #                                       $HOME/.bash_login $HOME/.profile\n    # Files (interactive non-login shells): $HOME/.bash_rc\n    #\n    # csh/tcsh\n    # Files: /etc/csh.cshrc /etc/csh.login\n    #\n    # zsh\n    # Files: /etc/zshenv /etc/zsh/zshenv $HOME/.zshenv /etc/zprofile\n    #        /etc/zsh/zprofile $HOME/.zprofile /etc/zshrc /etc/zsh/zshrc\n    #        $ZDOTDIR/.zshrc /etc/zlogin /etc/zsh/zlogin\n\n    SHELL_LOGIN_FILES=\"${ROOTDIR}etc/csh.cshrc ${ROOTDIR}etc/csh.login ${ROOTDIR}etc/zshenv ${ROOTDIR}etc/zsh/zshenv\n                       ${ROOTDIR}etc/zprofile ${ROOTDIR}etc/zsh/zprofile ${ROOTDIR}etc/zshrc ${ROOTDIR}etc/zsh/zshrc\n                       ${ROOTDIR}etc/zlogin ${ROOTDIR}etc/zsh/zlogin\"\n#\n#################################################################################\n#\n\n    # Test        : SHLL-6202\n    # Description : check all console TTYs in which root user can enter single user mode without password\n    Register --test-no SHLL-6202 --os FreeBSD --weight L --network NO --category security --description \"Check console TTYs\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking console TTYs\"\n        FIND=$(${GREPBINARY} -E '^console' ${ROOTDIR}etc/ttys | ${GREPBINARY} -v 'insecure')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking console TTYs\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: console is secured against single user mode without password.\"\n        else\n            Display --indent 2 --text \"- Checking console TTYs\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Found insecure console in ${ROOTDIR}etc/ttys. Single user mode login without password allowed!\"\n            LogText \"Output ${ROOTDIR}etc/ttys:\"\n            LogText \"${FIND}\"\n            ReportWarning \"${TEST_NO}\" \"Found unprotected console in ${ROOTDIR}etc/ttys\"\n            LogText \"Possible solution: Change the console line from 'secure' to 'insecure'.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SHLL-6211\n    # Description : Determine available shell according /etc/shells\n    Register --test-no SHLL-6211 --weight L --network NO --category security --description \"Available and valid shells\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for ${ROOTDIR}etc/shells\"\n        if [ -f ${ROOTDIR}etc/shells ]; then\n            LogText \"Result: Found ${ROOTDIR}etc/shells file\"\n            LogText \"Test: Reading available shells from ${ROOTDIR}etc/shells\"\n            SSHELLS=$(${GREPBINARY} \"^/\" ${ROOTDIR}etc/shells)\n            CSSHELLS=0; CSSHELLS_ALL=0\n            Display --indent 2 --text \"- Checking shells from ${ROOTDIR}etc/shells\"\n            for I in ${SSHELLS}; do\n                CSSHELLS_ALL=$((CSSHELLS_ALL + 1))\n                Report \"available_shell[]=${I}\"\n                # TODO add check for symlinked shells\n                if [ -f ${I} ]; then\n                    LogText \"Found installed shell: ${I}\"\n                    CSSHELLS=$((CSSHELLS + 1))\n                else\n                    LogText \"Shell ${I} not installed. Probably a dummy or non existing shell.\"\n                fi\n            done\n            Display --indent 4 --text \"Result: found ${CSSHELLS_ALL} shells (valid shells: ${CSSHELLS}).\"\n        else\n            LogText \"Result: ${ROOTDIR}etc/shells not found, skipping test\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SHLL-6220\n    # Description : Check for idle session killing tools or settings\n    Register --test-no SHLL-6220 --weight L --network NO --category security --description \"Idle session killing tools or settings\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        IDLE_TIMEOUT_METHOD=\"\"\n        IDLE_TIMEOUT_READONLY=\"\"\n\n        LogText \"Test: Search for session timeout tools or settings in shell\"\n        if IsRunning \"timeoutd\"; then\n            IDLE_TIMEOUT=1\n            LogText \"Result: found timeoutd process to kill idle sessions\"\n            IDLE_TIMEOUT_METHOD=\"timeout-daemon\"\n        fi\n        if IsRunning \"autolog\"; then\n            IDLE_TIMEOUT=1\n            LogText \"Result: found autolog process to kill idle sessions\"\n            Report \"session_timeout_method[]=autolog\"\n            IDLE_TIMEOUT_METHOD=\"autolog\"\n        fi\n\n        if [ -f ${ROOTDIR}etc/profile ]; then\n            # Determine if we can find a TMOUT value\n            FIND=$(${GREPBINARY} 'TMOUT=' ${ROOTDIR}etc/profile | ${TRBINARY} -d ' ' | ${TRBINARY} -d '\\t' | ${GREPBINARY} -v \"^#\" | ${SEDBINARY} 's/export//' | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} -F= '{ print $2 }')\n            # Determine if the value is exported (with export, readonly, or typeset)\n            FIND2=$(${GREPBINARY} '\\(export\\|readonly\\|typeset -r\\)[ \\t]*TMOUT' ${ROOTDIR}etc/profile | ${GREPBINARY} -v \"^#\" | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} '{ print $1 }')\n            if [ -n \"${FIND}\" ]; then\n                N=0; IDLE_TIMEOUT=1\n                for I in ${FIND}; do\n                    LogText \"Output: ${I}\"\n                    Report \"session_timeout_value[]=${I}\"\n                    N=$((N + 1))\n                done\n                if [ ${N} -eq 1 ]; then\n                    LogText \"Result: found TMOUT value configured in ${ROOTDIR}etc/profile\"\n                else\n                    LogText \"Result: found several TMOUT values configured in ${ROOTDIR}etc/profile\"\n                fi\n                IDLE_TIMEOUT_METHOD=\"profile\"\n            else\n                LogText \"Result: could not find TMOUT setting in ${ROOTDIR}etc/profile\"\n            fi\n\n            if [ -n \"${FIND2}\" ]; then\n                N=0;\n                for I in ${FIND2}; do\n                    LogText \"Output: ${I}\"\n                    if [ \"${I}\" = \"readonly\" -o \"${I}\" = \"typeset\" ]; then\n                        N=$((N + 1))\n                    fi\n                done\n                if [ ${N} -gt 0 ]; then\n                    LogText \"Result: found readonly setting in ${ROOTDIR}etc/profile (readonly or typeset -r)\"\n                    IDLE_TIMEOUT_READONLY=1\n                else\n                    LogText \"Result: NO readonly setting found in ${ROOTDIR}etc/profile (readonly or typeset -r)\"\n                    IDLE_TIMEOUT_READONLY=0\n                fi\n            else\n                LogText \"Result: could not find export, readonly or typeset -r in ${ROOTDIR}etc/profile\"\n            fi\n        else\n            LogText \"Result: skip ${ROOTDIR}etc/profile test, file not available on this system\"\n        fi\n\n        if [ -d ${ROOTDIR}etc/profile.d ]; then\n            FIND=$(${LSBINARY} ${ROOTDIR}etc/profile.d/*.sh 2> /dev/null)\n            if [ -n \"${FIND}\" ]; then\n                # Determine if we can find a TMOUT value\n                FIND=$(${FINDBINARY} -L ${ROOTDIR}etc/profile.d -name \"*.sh\" -type f -exec cat {} \\; 2> /dev/null | ${GREPBINARY} 'TMOUT=' | ${TRBINARY} -d ' ' | ${TRBINARY} -d '\\t' | ${GREPBINARY} -v \"^#\" | ${SEDBINARY} 's/export//' | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} -F= '{ print $2 }')\n                # Determine if the value is exported (with export, readonly, or typeset)\n                FIND2=$(${FINDBINARY} -L ${ROOTDIR}etc/profile.d -name \"*.sh\" -type f -exec cat {} \\; 2> /dev/null | ${GREPBINARY} '\\(export\\|readonly\\|typeset -r\\)[ \\t]*TMOUT' | ${GREPBINARY} -v \"^#\" | ${SEDBINARY} 's/#.*//' | ${AWKBINARY} '{ print $1 }')\n                if [ -n \"${FIND}\" ]; then\n                    N=0; IDLE_TIMEOUT=1\n                    for I in ${FIND}; do\n                        LogText \"Output: ${I}\"\n                        Report \"session_timeout_value[]=${I}\"\n                        N=$((N + 1))\n                    done\n                    if [ ${N} -eq 1 ]; then\n                        LogText \"Result: found TMOUT value configured in one of the files in ${ROOTDIR}etc/profile.d directory\"\n                    else\n                        LogText \"Result: found several TMOUT values configured in one of the files in ${ROOTDIR}etc/profile.d directory\"\n                    fi\n                    IDLE_TIMEOUT_METHOD=\"profile.d\"\n                else\n                    LogText \"Result: could not find TMOUT setting in ${ROOTDIR}etc/profile.d/*.sh\"\n                fi\n                # Check for readonly\n                if [ -n \"${FIND2}\" ]; then\n                    N=0;\n                    for I in ${FIND2}; do\n                        LogText \"Output: ${I}\"\n                        if [ \"${I}\" = \"readonly\" -o \"${I}\" = \"typeset\" ]; then\n                            N=$((N + 1))\n                        fi\n                    done\n                    if [ ${N} -gt 0 ]; then\n                        LogText \"Result: found readonly setting in ${ROOTDIR}etc/profile (readonly or typeset -r)\"\n                        IDLE_TIMEOUT_READONLY=1\n                    else\n                        LogText \"Result: NO readonly setting found in ${ROOTDIR}etc/profile (readonly or typeset -r)\"\n                        IDLE_TIMEOUT_READONLY=0\n                    fi\n                else\n                    LogText \"Result: could not find export, readonly or typeset -r in ${ROOTDIR}etc/profile\"\n                fi\n            fi\n        else\n            LogText \"Result: skip ${ROOTDIR}etc/profile.d directory test, directory not available on this system\"\n        fi\n\n        if [ -n \"${IDLE_TIMEOUT_METHOD}\" ]; then\n            Report \"session_timeout_method[]=${IDLE_TIMEOUT_METHOD}\"\n        fi\n        if [ -n \"${IDLE_TIMEOUT_READONLY}\" ]; then\n            Report \"session_timeout_set_readonly=${IDLE_TIMEOUT_READONLY}\"\n        fi\n\n        if [ ${IDLE_TIMEOUT} -eq 1 ]; then\n            Display --indent 4 --text \"- Session timeout settings/tools\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            Display --indent 4 --text \"- Session timeout settings/tools\" --result \"${STATUS_NONE}\" --color YELLOW\n            AddHP 1 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SHLL-6230\n    # Description : Check for umask values in shell configurations\n    SHELL_CONFIG_FILES=\"${ROOTDIR}etc/bashrc ${ROOTDIR}etc/bash.bashrc ${ROOTDIR}etc/bash.bashrc.local ${ROOTDIR}etc/csh.cshrc ${ROOTDIR}etc/profile\"\n    Register --test-no SHLL-6230 --weight H --network NO --category security --description \"Perform umask check for shell configurations\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        Display --indent 2 --text \"- Checking default umask values\"\n        for FILE in ${SHELL_CONFIG_FILES}; do\n            HARDENING_POSSIBLE=0\n            FIND=\"\"\n            if [ -f ${FILE} ]; then\n                LogText \"Result: file ${FILE} exists\"\n                FOUND=1\n                FIND=$(${GREPBINARY} umask ${FILE} | ${SEDBINARY} 's/^[ \\t]*//g' | ${SEDBINARY} 's/#.*$//' | ${GREPBINARY} -v \"^$\" | ${AWKBINARY} '{ print $2 }')\n                if IsEmpty \"${FIND}\"; then\n                    LogText \"Result: did not find umask configured in ${FILE}\"\n                    Display --indent 4 --text \"- Checking default umask in ${FILE}\" --result \"${STATUS_NONE}\" --color YELLOW\n                else\n                    for UMASKVALUE in ${FIND}; do\n                        LogText \"Result: found umask ${UMASKVALUE} in ${FILE}\"\n                        case ${UMASKVALUE} in\n                            027|0027|077|0077)\n                                    LogText \"Result: umask ${UMASKVALUE} is considered a properly hardened value\"\n                            ;;\n                            *)\n                                    LogText \"Result: umask ${UMASKVALUE} can be hardened \"\n                                    HARDENING_POSSIBLE=1\n                            ;;\n                        esac\n                    done\n                    if [ ${HARDENING_POSSIBLE} -eq 0 ]; then\n                        Display --indent 4 --text \"- Checking default umask in ${FILE}\" --result \"${STATUS_OK}\" --color GREEN\n                        AddHP 3 3\n                    else\n                        Display --indent 4 --text \"- Checking default umask in ${FILE}\" --result \"${STATUS_WEAK}\" --color YELLOW\n                        AddHP 1 3\n                    fi\n                fi\n            else\n                LogText \"Result: file ${FILE} not found\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n\nReport \"session_timeout_enabled=${IDLE_TIMEOUT}\"\n\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_snmp",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# SNMP related tests\n#\n#################################################################################\n#\n    SNMP_DAEMON_CONFIG_LOCS=\"${ROOTDIR}etc/snmp\"\n    SNMP_DAEMON_CONFIG=\"\"\n    SNMP_DAEMON_RUNNING=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_SNMP_SUPPORT}\"\n\n    # Test        : SNMP-3302\n    # Description : Check for a running SNMP daemon\n    Register --test-no SNMP-3302 --weight L --network NO --category security --description \"Check for running SNMP daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for a SNMP daemon\"\n        if IsRunning \"snmpd\"; then\n            SNMP_DAEMON_RUNNING=1\n            LogText \"Result: SNMP daemon is running\"\n            Display --indent 2 --text \"- Checking running SNMP daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: No running SNMP daemon found\"\n            Display --indent 2 --text \"- Checking running SNMP daemon\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SNMP-3304\n    # Description : Determine SNMP daemon configuration file location\n    if [ ${SNMP_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SNMP-3304 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check SNMP daemon file location\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching for snmpd.conf file\"\n        for I in ${SNMP_DAEMON_CONFIG_LOCS}; do\n            if [ -f \"${I}/snmpd.conf\" ]; then\n                LogText \"Result: ${I}/snmpd.conf exists\"\n                SNMP_DAEMON_CONFIG=\"${I}/snmpd.conf\"\n            fi\n        done\n        if [ -z \"${SNMP_DAEMON_CONFIG}\" ]; then\n            LogText \"Result: No snmpd configuration found\"\n            Display --indent 4 --text \"- Checking SNMP configuration\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        else\n            LogText \"Result: using last found configuration file: ${SNMP_DAEMON_CONFIG}\"\n            Display --indent 4 --text \"- Checking SNMP configuration\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SNMP-3306\n    # Description : Determine SNMP communities\n    if [ -n \"${SNMP_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SNMP-3306 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check SNMP communities\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        WARN=0\n        LogText \"Test: reading active snmp communities\"\n        FIND=$(${AWKBINARY} '/^com2sec/ { print $4 }' ${SNMP_DAEMON_CONFIG})\n        for I in ${FIND}; do\n            LogText \"Output: ${I}\"\n            if [ \"${I}\" = \"public\" -o \"${I}\" = \"private\" ]; then\n                LogText \"Result: found easy guessable snmp community string (${I})\"\n                WARN=1\n                AddHP 1 3\n            fi\n        done\n\n        # Check status of test\n        if [ ${WARN} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking SNMP community strings\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        else\n            Display --indent 2 --text \"- Checking SNMP community strings\" --result \"${STATUS_WARNING}\" --color RED\n            ReportWarning \"${TEST_NO}\" \"Found easy guessable SNMP community string\"\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_squid",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Squid\n#\n#################################################################################\n#\n    SQUID_DAEMON_CONFIG_LOCS=\"${ROOTDIR}etc ${ROOTDIR}etc/squid ${ROOTDIR}etc/squid3 ${ROOTDIR}usr/local/etc/squid ${ROOTDIR}usr/local/squid/etc\"\n    SQUID_DAEMON_CONFIG=\"\"\n    SQUID_DAEMON_UNSAFE_PORTS_LIST=\"22 23 25\"\n    SQUID_DAEMON_RUNNING=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_SQUID_SUPPORT}\"\n#\n#################################################################################\n#\n    # Test        : SQD-3602\n    # Description : Check for a running Squid daemon\n    # Notes       : Search for squid(3) with a space, to avoid SquidGuard and other\n    #               programs.\n    Register --test-no SQD-3602 --weight L --network NO --category security --description \"Check for running Squid daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for a Squid daemon\"\n        FOUND=0\n        # Check running processes\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} -E \"(squid|squid3) \" | ${GREPBINARY} -v \"grep\")\n        if [ -n \"${FIND}\" ]; then\n            SQUID_DAEMON_RUNNING=1\n            LogText \"Result: Squid daemon is running\"\n            Display --indent 2 --text \"- Checking running Squid daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: No running Squid daemon found\"\n            Display --indent 2 --text \"- Checking running Squid daemon\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3604\n    # Description : Determine Squid daemon configuration file location\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3604 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid daemon file location\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching for squid.conf or squid3.conf file\"\n        for I in ${SQUID_DAEMON_CONFIG_LOCS}; do\n            # Checking squid.conf\n            if [ -f \"${I}/squid.conf\" ]; then\n                LogText \"Result: ${I}/squid.conf exists\"\n                SQUID_DAEMON_CONFIG=\"${I}/squid.conf\"\n            fi\n            # Checking squid3.conf\n            if [ -f \"${I}/squid3.conf\" ]; then\n                LogText \"Result: ${I}/squid3.conf exists\"\n                SQUID_DAEMON_CONFIG=\"${I}/squid3.conf\"\n            fi\n        done\n        if [ -z \"${SQUID_DAEMON_CONFIG}\" ]; then\n            LogText \"Result: No Squid configuration file found\"\n            Display --indent 4 --text \"- Searching Squid configuration file\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n        else\n            LogText \"Result: using last found configuration file: ${SQUID_DAEMON_CONFIG}\"\n            Display --indent 4 --text \"- Searching Squid configuration\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3606\n    # Description : Check Squid version\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3606 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid version\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ -n \"${SQUIDBINARY}\" ]; then\n            LogText \"Result: Squid binary found (${SQUIDBINARY})\"\n            # Skip check if a setuid/setgid bit is found\n            FIND=$(${FINDBINARY} ${SQUIDBINARY} \\( -perm 4000 -o -perm 2000 \\) -print)\n            if [ -z \"${FIND}\" ]; then\n                FIND2=$(${SQUIDBINARY} -v | ${AWKBINARY} '{ if ($3==\"Version\") { print $4 } }')\n                Display --indent 4 --text \"- Checking Squid version\" --result \"${STATUS_FOUND}\" --color GREEN\n                SQUID_VERSION=\"${FIND2}\"\n            else\n                LogText \"Result: test skipped for security reasons, setuid/setgid bit set\"\n                Display --indent 4 --text \"- Checking Squid version\" --result \"${STATUS_SKIPPED}\" --color RED\n            fi\n        else\n            LogText \"Result: no Squid binary found\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3610\n    # Description : Check Squid configuration options\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3610 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Gather Squid settings\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking all specific defined options in ${SQUID_DAEMON_CONFIG}\"\n        FIND=$(${GREPBINARY} -v \"^#\" ${SQUID_DAEMON_CONFIG} | ${GREPBINARY} -v \"^$\" | ${AWKBINARY} '{gsub(\"\\t\",\" \");print}' | ${SEDBINARY} 's/ /!space!/g')\n        for I in ${FIND}; do\n            I=$(echo ${I} | ${SEDBINARY} 's/!space!/ /g')\n            LogText \"Found Squid option: ${I}\"\n            Report \"squid_option=${I}\"\n        done\n        Display --indent 4 --text \"- Checking defined Squid options\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3613\n    # Description : Check Squid configuration file permissions\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3613 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid file permissions\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking file permissions of ${SQUID_DAEMON_CONFIG}\"\n        FIND=$(find -L ${SQUID_DAEMON_CONFIG} -type f -a \\( -perm -004 -o -perm -002 -o -perm -001 \\))\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: file ${SQUID_DAEMON_CONFIG} is world readable, writable or executable and could leak information or passwords\"\n            Display --indent 4 --text \"- Checking Squid configuration file permissions\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check file permissions of ${SQUID_DAEMON_CONFIG} to limit access\"\n            ReportWarning \"${TEST_NO}\" \"File permissions of ${SQUID_DAEMON_CONFIG} are not restrictive\"\n            AddHP 0 2\n        else\n            LogText \"Result: file ${SQUID_DAEMON_CONFIG} has proper file permissions\"\n            Display --indent 4 --text \"- Checking Squid configuration file permissions\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then\n        Display --indent 4 --text \"- Checking Squid access control\"\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3614\n    # Description : Check Squid authentication\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3614 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid authentication methods\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check auth_param option for authentication methods\"\n        FIND=$(${GREPBINARY} \"^auth_param\" ${SQUID_DAEMON_CONFIG} | ${AWKBINARY} '{ print $2 }')\n        if [ -z \"${FIND}\" ]; then\n            LogText \"No auth_param option found, proxy access anonymous or based on other methods (like ACLs)\"\n            Display --indent 6 --text \"- Checking Squid authentication methods\" --result \"${STATUS_NONE}\" --color YELLOW\n        else\n            Display --indent 6 --text \"- Checking Squid authentication methods\" --result \"${STATUS_FOUND}\" --color GREEN\n            for I in ${FIND}; do\n                LogText \"Result: found authentication method ${I}\"\n                Report \"squid_auth_method=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3616\n    # Description : Check external Squid authentication\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3616 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check external Squid authentication\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check external_acl_type option for external authentication helpers\"\n        FIND=$(${GREPBINARY} \"^external_acl_type\" ${SQUID_DAEMON_CONFIG})\n        if [ -z \"${FIND}\" ]; then\n            LogText \"No external_acl_type found\"\n            Display --indent 6 --text \"- Checking Squid external authentication methods\" --result \"${STATUS_NONE}\" --color YELLOW\n        else\n            Display --indent 6 --text \"- Checking Squid external authentication methods\" --result \"${STATUS_FOUND}\" --color GREEN\n            for I in ${FIND}; do\n                LogText \"Result: found external authentication method helper\"\n                LogText \"Output: ${FIND}\"\n                #Report \"squid_external_acl_type=TRUE\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3620\n    # Description : Check ACLs\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a ! \"${SQUID_DAEMON_CONFIG}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3620 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid access control lists\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: checking ACLs\"\n        FIND=$(${GREPBINARY} \"^acl \" ${SQUID_DAEMON_CONFIG} | ${SEDBINARY} 's/ /!space!/g')\n        if [ \"${FIND}\" = \"\" ]; then\n            LogText \"Result: No ACLs found\"\n            Display --indent 6 --text \"- Checking Access Control Lists\" --result \"${STATUS_NONE}\" --color RED\n        else\n            for ITEM in ${FIND}; do\n                COUNT=$((COUNT + 1))\n                ITEM=$(echo ${ITEM} | ${SEDBINARY} 's/!space!/ /g')\n                LogText \"Found ACL: ${ITEM}\"\n                #Report \"squid_acl=${ITEM}\" # TODO\n            done\n            LogText \"Result: Found ${COUNT} ACLs\"\n            Display --indent 6 --text \"- Checking Access Control Lists\" --result \"${COUNT} ACLs FOUND\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3624\n    # Description : Check insecure ports in Safe_ports list\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a ! \"${SQUID_DAEMON_CONFIG}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3624 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid safe ports\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking ACL Safe_ports http_access option\"\n        FIND=$(${GREPBINARY} \"^http_access\" ${SQUID_DAEMON_CONFIG} | ${GREPBINARY} \"Safe_ports\")\n        if IsEmpty \"${FIND}\"; then\n            LogText \"Result: no Safe_ports found\"\n            Display --indent 6 --text \"- Checking ACL 'Safe_ports' http_access option\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Check if Squid has been configured to restrict access to all safe ports\"\n        else\n            LogText \"Result: checking ACL safe ports\"\n            FIND2=$(${GREPBINARY} \"^acl Safe_ports port\" ${SQUID_DAEMON_CONFIG} | ${AWKBINARY} '{ print $4 }')\n            if IsEmpty \"${FIND2}\"; then\n                Display --indent 6 --text \"- Checking ACL 'Safe_ports' ports\" --result \"NONE FOUND\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Check if Squid has been configured for which ports it can allow outgoing traffic (Safe_ports)\"\n                AddHP 0 1\n            else\n                LogText \"Result: Safe_ports found\"\n                for ITEM in ${FIND}; do\n                    LogText \"Found safe port: ${ITEM}\"\n                done\n                Display --indent 6 --text \"- Checking ACL 'Safe_ports' ports\" --result \"${STATUS_FOUND}\" --color GREEN\n                AddHP 1 1\n            fi\n\n            for ITEM in ${SQUID_DAEMON_UNSAFE_PORTS_LIST}; do\n                LogText \"Test: Checking port ${ITEM} in Safe_ports list\"\n                FIND2=$(${GREPBINARY} -w \"^acl Safe_ports port ${ITEM}\" ${SQUID_DAEMON_CONFIG})\n                if IsEmpty \"${FIND2}\"; then\n                    Display --indent 6 --text \"- Checking ACL 'Safe_ports' (port ${ITEM})\" --result \"${STATUS_NOT_FOUND}\" --color GREEN\n                    AddHP 1 1\n                else\n                    Display --indent 6 --text \"- Checking ACL 'Safe_ports' (port ${ITEM})\" --result \"${STATUS_FOUND}\" --color RED\n                    ReportWarning \"${TEST_NO}\" \"Squid configuration possibly allows relaying traffic via configured Safe_port ${ITEM}\"\n                    AddHP 0 1\n                fi\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then\n        Display --indent 4 --text \"- Checking Squid Denial of Service tuning options\"\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3630 [T]\n    # Description : Check reply_body_max_size value\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3630 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid reply_body_max_size option\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: checking option reply_body_max_size\"\n        FIND=$(${GREPBINARY} \"^reply_body_max_size \" ${SQUID_DAEMON_CONFIG} | ${SEDBINARY} 's/ /!space!/g')\n        if IsEmpty \"${FIND}\"; then\n            LogText \"Result: option reply_body_max_size not configured\"\n            Display --indent 6 --text \"- Checking option: reply_body_max_size\" --result \"${STATUS_NONE}\" --color RED\n            AddHP 1 2\n            ReportSuggestion \"${TEST_NO}\" \"Configure Squid option reply_body_max_size to limit the upper size of requests.\"\n        else\n            LogText \"Result: option reply_body_max_size configured\"\n            LogText \"Output: ${FIND}\"\n            Display --indent 6 --text \"- Checking option: reply_body_max_size\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then\n        Display --indent 4 --text \"- Checking Squid general options\"\n    fi\n#\n#################################################################################\n#\n    # Test        : SQD-3680\n    # Description : Check httpd_suppress_version_string\n    if [ ${SQUID_DAEMON_RUNNING} -eq 1 -a -n \"${SQUID_DAEMON_CONFIG}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SQD-3680 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Squid version suppression\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${GREPBINARY} \"^httpd_suppress_version_string \" ${SQUID_DAEMON_CONFIG} | ${GREPBINARY} \" on\")\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: option httpd_suppress_version_string not configured\"\n            Display --indent 6 --text \"- Checking option: httpd_suppress_version_string\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            AddHP 1 2\n            ReportSuggestion \"${TEST_NO}\" \"Configure Squid option httpd_suppress_version_string (on) to suppress the version.\"\n        else\n            LogText \"Result: option httpd_suppress_version_string configured\"\n            LogText \"Output: ${FIND}\"\n            Display --indent 6 --text \"- Checking option: httpd_suppress_version_string\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 2 2\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_ssh",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# SSH\n#\n#################################################################################\n#\n    SSH_DAEMON_CONFIG_LOCS=\"/etc /etc/ssh /usr/local/etc/ssh /opt/csw/etc/ssh /usr/etc/ssh\"\n    SSH_DAEMON_CONFIG=\"\"\n    SSH_DAEMON_PORT=\"\"\n    SSH_DAEMON_RUNNING=0\n    SSH_DAEMON_OPTIONS_FILE=\"\"\n    OPENSSHD_RUNNING=0\n    OPENSSHD_VERSION=0\n    OPENSSHD_VERSION_MAJOR=0\n    OPENSSHD_VERSION_MINOR=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_SSH_SUPPORT}\"\n#\n#################################################################################\n#\n    # Test        : SSH-7402\n    # Description : Check for a running SSH daemon\n    Register --test-no SSH-7402 --weight L --network NO --category security --description \"Check for running SSH daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Searching for a SSH daemon\"\n        if IsRunning \"sshd\"; then\n            OPENSSHD_RUNNING=1\n            SSH_DAEMON_RUNNING=1\n            Display --indent 2 --text \"- Checking running SSH daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n            # Store settings in a temporary file\n            CreateTempFile\n            SSH_DAEMON_OPTIONS_FILE=\"${TEMP_FILE}\"\n            # Use a non-existing user, to ensure that systems that have a Match block configured, will be evaluated as well\n            ${SSHDBINARY} -T -C user=doesnotexist,host=none,addr=none 2> /dev/null > ${SSH_DAEMON_OPTIONS_FILE}\n        elif PortIsListening \"TCP\" 22; then\n            Display --indent 2 --text \"- Checking running SSH daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n            SSH_DAEMON_RUNNING=1\n        else\n            Display --indent 2 --text \"- Checking running SSH daemon\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SSH-7404\n    # Description : Determine SSH daemon configuration file location\n    if [ ${OPENSSHD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SSH-7404 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check SSH daemon file location\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: searching for sshd_config file\"\n        for I in ${SSH_DAEMON_CONFIG_LOCS}; do\n            if [ -f \"${I}/sshd_config\" ]; then\n                LogText \"Result: ${I}/sshd_config exists\"\n                if [ ${FOUND} -eq 1 ]; then\n                    ReportException \"${TEST_NO}:01\"\n                    LogText \"Result: we already found another sshd_config file. Using this new file instead of the previous one.\"\n                fi\n                FileIsReadable ${I}/sshd_config\n                if [ ${CANREAD} -eq 1 ]; then\n                    FOUND=1\n                    SSH_DAEMON_CONFIG=\"${I}/sshd_config\"\n                else\n                    LogText \"Result: can not read ${I}/sshd_config file (no permission)\"\n                fi\n            fi\n        done\n        if [ -z \"${SSH_DAEMON_CONFIG}\" ]; then\n            LogText \"Result: No sshd configuration found\"\n            Display --indent 4 --text \"- Searching SSH configuration\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            ReportException \"${TEST_NO}:1\" \"SSH daemon is running, but no readable configuration file found\"\n        else\n            LogText \"Result: using last found configuration file: ${SSH_DAEMON_CONFIG}\"\n            Display --indent 4 --text \"- Searching SSH configuration\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SSH-7406\n    # Description : Check OpenSSH version\n    if [ ${OPENSSHD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SSH-7406 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Determine OpenSSH version\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        OPENSSHD_VERSION=$(${SSHDBINARY} -t -d 2>&1 | ${GREPBINARY} 'sshd version' | ${AWKBINARY} '{if($4~OpenSSH_){print $4}}' | ${AWKBINARY} -F_ '{print $2}' | ${TRBINARY} -d '[:cntrl:],')\n        LogText \"Result: discovered OpenSSH version is ${OPENSSHD_VERSION}\"\n        if [ -n \"${OPENSSHD_VERSION}\" ]; then\n            OPENSSHD_VERSION_MAJOR=$(echo ${OPENSSHD_VERSION%%p*} | ${AWKBINARY} -F. '{print $1}')\n            LogText \"Result: OpenSSH major version: ${OPENSSHD_VERSION_MAJOR}\"\n            OPENSSHD_VERSION_MINOR=$(echo ${OPENSSHD_VERSION%%p*} | ${AWKBINARY} -F. '{print $2}')\n            LogText \"Result: OpenSSH minor version: ${OPENSSHD_VERSION_MINOR}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : SSH-7408\n    # Description : Check SSH specific defined options\n    # Notes       : Instead of parsing the configuration file, we query the SSH daemon itself\n    if [ ${OPENSSHD_RUNNING} -eq 1 -a -n \"${SSH_DAEMON_OPTIONS_FILE}\" -a \\( ${OPENSSHD_VERSION_MAJOR} -gt 5 -o ${OPENSSHD_VERSION_MAJOR} -eq 5 -a ${OPENSSHD_VERSION_MINOR} -ge 1 \\) ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SSH-7408 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check SSH specific defined options\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking specific defined options in ${SSH_DAEMON_OPTIONS_FILE}\"\n        ## SSHOPTIONS scheme:\n        ##      <OptionName>:<ExpectedValue>,<MediumScoreValue>,<WeakValue>:<TestType>\n        ##\n        ##      Test types:\n        ##      (a) '='         -- equal to is better,\n        ##      (b) '<'         -- less or equal is better,\n        ##      (c) '>'         -- more or equal is better,\n        ##      (d) '!'         -- not equal is better.\n        ##\n        ##      Example:\n        ##      PermitRootLogin:NO,WITHOUT-PASSWORD,YES,:=\n        SSHOPS=\"AllowTcpForwarding:NO,LOCAL,YES:=\\\n                ClientAliveCountMax:2,4,16:<\\\n                ClientAliveInterval:300,600,900:<\\\n                FingerprintHash:SHA256,MD5,:=\\\n                GatewayPorts:NO,,YES:=\\\n                IgnoreRhosts:YES,,NO:=\\\n                LoginGraceTime:120,240,480:<\\\n                LogLevel:VERBOSE,INFO,:=\\\n                MaxAuthTries:3,6,999:<\\\n                MaxSessions:2,4,8:<\\\n                PermitRootLogin:(FORCED-COMMANDS-ONLY|NO|PROHIBIT-PASSWORD|WITHOUT-PASSWORD),,YES:=\\\n                PermitUserEnvironment:NO,,YES:=\\\n                PermitTunnel:NO,,YES:=\\\n                Port:,,22:!\\\n                PrintLastLog:YES,,NO:=\\\n                StrictModes:YES,,NO:=\\\n                TCPKeepAlive:NO,,YES:=\\\n                UseDNS:NO,,YES:=\\\n                X11Forwarding:NO,,YES:=\\\n                AllowAgentForwarding:NO,,YES:=\"\n\n\n        # OpenSSH had some options removed over time. Based on the version we add some additional options to check\n        if [ ${OPENSSHD_VERSION_MAJOR} -lt 7 ]; then\n            LogText \"Result: added additional options for OpenSSH 6.x and lower\"\n            SSHOPS=\"${SSHOPS} Compression:(DELAYED|NO),,YES:= UsePrivilegeSeparation:SANDBOX,YES,NO:=  Protocol:2,,1:=\"\n        elif [ ${OPENSSHD_VERSION_MAJOR} -eq 7 ]; then\n            # Protocol 1 support removed (OpenSSH 7.4 and later)\n            if [ ${OPENSSHD_VERSION_MINOR} -lt 4 ]; then\n                LogText \"Result: added additional options for OpenSSH < 7.4\"\n                SSHOPS=\"${SSHOPS} Compression:(DELAYED|NO),,YES:= Protocol:2,,1:=\"\n            fi\n            # UsePrivilegedSeparation removed (OpenSSH 7.5 and later)\n            if [ ${OPENSSHD_VERSION_MINOR} -lt 5 ]; then\n                LogText \"Result: added additional options for OpenSSH < 7.5\"\n                SSHOPS=\"${SSHOPS} UsePrivilegeSeparation:SANDBOX,YES,NO:=\"\n            fi\n        fi\n\n        # Go through our list of options\n        for I in ${SSHOPS}; do\n            OPTIONNAME=$(echo ${I} | ${CUTBINARY} -d ':' -f1)\n            OPTIONNAME_LOWER=$(echo ${I} | ${CUTBINARY} -d ':' -f1 | ${AWKBINARY} '{ print tolower($1) }')\n            EXPECTEDVALUE=$(echo ${I} | ${CUTBINARY} -d ':' -f2 | ${CUTBINARY} -d',' -f1)\n            MEDIUMSCOREDVALUE=$(echo ${I} | ${CUTBINARY} -d ':' -f2 | ${CUTBINARY} -d',' -f2)\n            WEAKVALUE=$(echo ${I} | ${CUTBINARY} -d ':' -f2 | ${CUTBINARY} -d',' -f3)\n            TESTTYPE=$(echo ${I} | ${CUTBINARY} -d ':' -f3)\n            RESULT=\"NONE\"\n\n            if ! SkipAtomicTest \"${TEST_NO}:${OPTIONNAME_LOWER}\"; then\n\n                # Get value and use the last occurrence\n                FOUNDVALUE=$(${AWKBINARY} -v OPT=\"${OPTIONNAME_LOWER}\" 'index($0, OPT) == 1 { print toupper($2) }' ${SSH_DAEMON_OPTIONS_FILE} | tail -1)\n                LogText \"Test: Checking ${OPTIONNAME} in ${SSH_DAEMON_OPTIONS_FILE}\"\n\n                if [ -n \"${FOUNDVALUE}\" ]; then\n                    LogText \"Result: Option ${OPTIONNAME} found\"\n                    LogText \"Result: Option ${OPTIONNAME} value is ${FOUNDVALUE}\"\n\n                    if [ \"${TESTTYPE}\" = \"=\" ]; then\n                        if [ \"${FOUNDVALUE}\" = \"${EXPECTEDVALUE}\" ]; then\n                            RESULT=\"GOOD\"\n                        elif [ \"${FOUNDVALUE}\" = \"${MEDIUMSCOREDVALUE}\" ]; then\n                            RESULT=\"MIDSCORED\"\n                        elif [ \"${FOUNDVALUE}\" = \"${WEAKVALUE}\" ]; then\n                            RESULT=\"WEAK\"\n                        else\n                            if [ -n \"${EXPECTEDVALUE}\" ]; then\n                                LogText \"Expected value has multiple values, testing if active value is in list (${EXPECTEDVALUE})\"\n                                FIND=$(echo ${FOUNDVALUE} | ${GREPBINARY} -E \"${EXPECTEDVALUE}\")\n                                if [ $? -eq 0 ]; then\n                                    LogText \"Result: found\"\n                                    RESULT=\"GOOD\"\n                                else\n                                    LogText \"Result: not found\"\n                                fi\n                            fi\n                            if [ -n \"${MEDIUMSCOREDVALUE}\" ]; then\n                                LogText \"Medium scored value has multiple values, testing if active value is in list (${MEDIUMSCOREDVALUE})\"\n                                FIND=$(echo ${FOUNDVALUE} | ${GREPBINARY} -E \"${MEDIUMSCOREDVALUE}\")\n                                if [ $? -eq 0 ]; then\n                                    LogText \"Result: found\"\n                                    RESULT=\"MIDSCORED\"\n                                else\n                                    LogText \"Result: not found\"\n                                fi\n                            fi\n                            # Set result to weak if we can't find any matches\n                            if [ \"${RESULT}\" = \"NONE\" ]; then RESULT=\"WEAK\"; fi\n                        fi\n\n                    elif [ \"${TESTTYPE}\" = \"<\" ]; then\n                        if [ \"${FOUNDVALUE}\" -ge \"${WEAKVALUE}\" -o \"${FOUNDVALUE}\" -gt \"${MEDIUMSCOREDVALUE}\" ]; then\n                            RESULT=\"WEAK\"\n                        elif [ \"${FOUNDVALUE}\" -le \"${MEDIUMSCOREDVALUE}\" -a \"${FOUNDVALUE}\" -gt \"${EXPECTEDVALUE}\" ]; then\n                            RESULT=\"MIDSCORED\"\n                        elif [ \"${FOUNDVALUE}\" -le \"${EXPECTEDVALUE}\" ]; then\n                            RESULT=\"GOOD\"\n                        else\n                            RESULT=\"UNKNOWN\"\n                        fi\n\n                    elif [ \"${TESTTYPE}\" = \">\" ]; then\n                        if [ \"${FOUNDVALUE}\" -le \"${WEAKVALUE}\" ]; then\n                            RESULT=\"WEAK\"\n                        elif [ \"${FOUNDVALUE}\" -le \"${WEAKVALUE}\" -a \"${FOUNDVALUE}\" -ge \"${MEDIUMSCOREDVALUE}\" ]; then\n                            RESULT=\"MIDSCORED\"\n                        elif [ \"${FOUNDVALUE}\" -ge \"${EXPECTEDVALUE}\" ]; then\n                            RESULT=\"GOOD\"\n                        else\n                            RESULT=\"UNKNOWN\"\n                        fi\n\n                    elif [ \"${TESTTYPE}\" = \"!\" ]; then\n                        if [ \"${FOUNDVALUE}\" = \"${WEAKVALUE}\" ]; then\n                            RESULT=\"WEAK\"\n                        elif [ ! \"${FOUNDVALUE}\" = \"${WEAKVALUE}\" ]; then\n                            RESULT=\"GOOD\"\n                        else\n                            RESULT=\"UNKNOWN\"\n                        fi\n\n                    else\n                        RESULT=\"NONE\"\n                    fi\n                fi\n\n                if [ \"${RESULT}\" = \"GOOD\" ]; then\n                    LogText \"Result: OpenSSH option ${OPTIONNAME} is configured very well\"\n                    Display --indent 4 --text \"- OpenSSH option: ${OPTIONNAME}\" --result \"${STATUS_OK}\" --color GREEN\n                    AddHP 3 3\n                elif [ \"${RESULT}\" = \"MIDSCORED\" ]; then\n                    LogText \"Result: OpenSSH option ${OPTIONNAME} is configured reasonably\"\n                    ReportSuggestion \"${TEST_NO}\" \"Consider hardening SSH configuration\" \"${OPTIONNAME} (set ${FOUNDVALUE} to ${EXPECTEDVALUE})\" \"-\"\n                    ReportDetails --test \"${TEST_NO}\" --service \"sshd\" --field \"${OPTIONNAME}\" --value \"${FOUNDVALUE}\" --preferredvalue \"${EXPECTEDVALUE}\" --description \"sshd option ${OPTIONNAME}\"\n                    Display --indent 4 --text \"- OpenSSH option: ${OPTIONNAME}\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    AddHP 1 3\n                elif [ \"${RESULT}\" = \"WEAK\" ]; then\n                    LogText \"Result: OpenSSH option ${OPTIONNAME} is in a weak configuration state and should be fixed\"\n                    ReportSuggestion \"${TEST_NO}\" \"Consider hardening SSH configuration\" \"${OPTIONNAME} (set ${FOUNDVALUE} to ${EXPECTEDVALUE})\" \"-\"\n                    ReportDetails --test \"${TEST_NO}\" --service \"sshd\" --field \"${OPTIONNAME}\" --value \"${FOUNDVALUE}\" --preferredvalue \"${EXPECTEDVALUE}\" --description \"sshd option ${OPTIONNAME}\"\n                    Display --indent 4 --text \"- OpenSSH option: ${OPTIONNAME}\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                    AddHP 0 3\n                elif [ \"${RESULT}\" = \"UNKNOWN\" ]; then\n                    LogText \"Result: Value of OpenSSH option ${OPTIONNAME} is unknown (not defined)\"\n                    Display --indent 4 --text \"- OpenSSH option: ${OPTIONNAME}\" --result DEFAULT --color WHITE\n                    Report \"unknown_config_option[]=ssh|$SSH_DAEMON_CONFIG}|${OPTIONNAME}|\"\n                else\n                    LogText \"Result: Option ${OPTIONNAME} not found in output\"\n                    Display --indent 4 --text \"- OpenSSH option: ${OPTIONNAME}\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n                fi\n            else\n                if IsVerbose; then Display --indent 4 --text \"- OpenSSH option: ${OPTIONNAME}\" --result \"SKIPPED (via config)\" --color WHITE; fi\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : SSH-7440\n    # Description : OpenSSH - AllowUsers / AllowGroups\n    # Goal        : Check if only a specific amount of users/groups can log in to the system\n    if [ ${OPENSSHD_RUNNING} -eq 1 -a -n \"${SSH_DAEMON_OPTIONS_FILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no SSH-7440 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check OpenSSH option: AllowUsers and AllowGroups\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        # AllowUsers\n        FIND=$(${GREPBINARY} -E -i \"^AllowUsers\" ${SSH_DAEMON_OPTIONS_FILE} | ${AWKBINARY} '{ print $2 }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: AllowUsers set, with value ${FIND}\"\n            Display --indent 4 --text \"- OpenSSH option: AllowUsers\" --result \"${STATUS_FOUND}\" --color GREEN\n            FOUND=1\n        else\n            LogText \"Result: AllowUsers is not set\"\n            Display --indent 4 --text \"- OpenSSH option: AllowUsers\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n\n        # AllowGroups\n        FIND=$(${GREPBINARY} -E -i \"^AllowGroups\" ${SSH_DAEMON_OPTIONS_FILE} | ${AWKBINARY} '{ print $2 }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: AllowGroups set ${FIND}\"\n            Display --indent 4 --text \"- OpenSSH option: AllowGroups\" --result \"${STATUS_FOUND}\" --color GREEN\n            FOUND=1\n        else\n            LogText \"Result: AllowGroups is not set\"\n            Display --indent 4 --text \"- OpenSSH option: AllowGroups\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: SSH is limited to a specific set of users, which is good\"\n            AddHP 2 2\n        else\n            LogText \"Result: SSH has no specific user or group limitation. Most likely all valid users can SSH to this machine.\"\n            AddHP 0 1\n        fi\n    fi\n#\n#################################################################################\n#\n\nReport \"ssh_daemon_running=${SSH_DAEMON_RUNNING}\"\nReport \"openssh_daemon_running=${OPENSSHD_RUNNING}\"\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_storage",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_STORAGE}\"\n#\n#################################################################################\n#\n    AUTOMOUNTER_DAEMON_RUNNING=0\n    NFS_DAEMON_RUNNING=0\n    AUTOMOUNTER_DAEMON_TOOL=\"\"\n#\n#################################################################################\n#\n    # Test        : STRG-1846\n    # Description : Check for disabled firewire storage\n    # Explanation : Best option is to use the install function, otherwise drivers can still be loaded manually\n    Register --test-no STRG-1846 --os Linux --weight L --network NO --category security --description \"Check if firewire storage is disabled\"\n    if [ \"${SKIPTEST}\" -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: Checking firewire storage driver in directory /etc/modprobe.d and configuration file /etc/modprobe.conf\"\n        if [ -d \"${ROOTDIR}etc/modprobe.d\" ]; then\n            FIND=$(${LSBINARY} ${ROOTDIR}etc/modprobe.d/* 2> /dev/null)\n            if [ -n \"${FIND}\" ]; then\n                FIND1=$(${GREPBINARY} -E \"blacklist (ohci1394|firewire[-_]ohci|firewire-core)\" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v \"#\")\n                FIND2=$(${GREPBINARY} -E \"install (ohci1394|firewire[-_]ohci|firewire-core) /bin/(false|true)\" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v \"#\")\n                if [ -n \"${FIND1}\" ] || [ -n \"${FIND2}\" ]; then\n                    FOUND=1\n                    LogText \"Result: found firewire ohci driver in disabled state\"\n                fi\n            else\n                LogText \"Result: skipping ${ROOTDIR}etc/modprobe.d, directory found but no files in it\"\n            fi\n        fi\n        if [ -f \"${ROOTDIR}etc/modprobe.conf\" ]; then\n            FIND1=$(${GREPBINARY} -E -r \"blacklist (ohci1394|firewire[-_]ohci|firewire-core)\" \"${ROOTDIR}etc/modprobe.conf\" | ${GREPBINARY} -v \"#\")\n            FIND2=$(${GREPBINARY} -E -r \"install (ohci1394|firewire[-_]ohci|firewire-core) /bin/(false|true)\" \"${ROOTDIR}etc/modprobe.conf\" | ${GREPBINARY} -v \"#\")\n            if [ -n \"${FIND1}\" ] || [ -n \"${FIND2}\" ]; then\n                FOUND=1\n                LogText \"Result: found firewire ohci driver in disabled state\"\n            fi\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: firewire ohci driver is not explicitly disabled\"\n            Display --indent 2 --text \"- Checking firewire ohci driver (modprobe config)\" --result \"${STATUS_NOT_DISABLED}\" --color WHITE\n            ReportSuggestion \"${TEST_NO}\" \"Disable drivers like firewire storage when not used, to prevent unauthorized storage or data theft\"\n            # after blacklisting modules, make sure to remove them from the initram filesystem: update-initramfs -u\n            AddHP 2 3\n        else\n            LogText \"Result: firewire ohci driver is disabled\"\n            Display --indent 2 --text \"- Checking firewire ohci driver (modprobe config)\" --result \"${STATUS_DISABLED}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_storage_nfs",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# NFS\n#\n#################################################################################\n#\n    InsertSection \"NFS\"\n#\n#################################################################################\n#\n    NFS_DAEMON_RUNNING=0\n    NFS_EXPORTS_EMPTY=0\n#\n#################################################################################\n#\n    # Test        : STRG-1902\n    # Description : Check rpcinfo\n    if [ -n \"${RPCINFOBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no STRG-1902 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check rpcinfo registered programs\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking rpcinfo registered programs\"\n        FIND=$(${RPCINFOBINARY} -p 2> /dev/null | ${TRBINARY} -s ' ' ',')\n        for I in ${FIND}; do\n            LogText \"rpcinfo: ${I}\"\n        done\n        Display --indent 2 --text \"- Query rpc registered programs\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : STRG-1904\n    # Description : Check nfs versions in rpcinfo\n    if [ -n \"${RPCINFOBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no STRG-1904 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nfs rpc\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking NFS registered versions\"\n        FIND=$(${RPCINFOBINARY} -p 2> /dev/null | ${AWKBINARY} '{ if ($5==\"nfs\") { print $2 } }' | uniq | sort)\n        for I in ${FIND}; do\n            LogText \"Found version: ${I}\"\n        done\n        Display --indent 2 --text \"- Query NFS versions\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : STRG-1906\n    # Description : Check nfs protocols (TCP/UDP) and port in rpcinfo\n    if [ -n \"${RPCINFOBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no STRG-1906 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nfs rpc\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking NFS registered protocols\"\n        FIND=$(${RPCINFOBINARY} -p 2> /dev/null | ${AWKBINARY} '{ if ($5==\"nfs\") { print $3 } }' | uniq | sort)\n        for I in ${FIND}; do\n            LogText \"Found protocol: ${I}\"\n        done\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Output: no NFS protocols found\"\n        fi\n\n        # Check port number\n        LogText \"Test: Checking NFS registered ports\"\n        FIND=$(${RPCINFOBINARY} -p 2> /dev/null | ${AWKBINARY} '{ if ($5==\"nfs\") { print $3 } }' | uniq | sort)\n        for I in ${FIND}; do\n            LogText \"Found port: ${I}\"\n        done\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Output: no NFS port number found\"\n        fi\n        Display --indent 2 --text \"- Query NFS protocols\" --result \"${STATUS_DONE}\" --color GREEN\n    fi\n#\n#################################################################################\n#\n    # Test        : STRG-1920\n    # Description : Check for running NFS daemons\n    Register --test-no STRG-1920 --weight L --network NO --category security --description \"Checking NFS daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking running NFS daemon\"\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} \"nfsd\" | ${GREPBINARY} -v \"grep\")\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Output: NFS daemon is not running\"\n            Display --indent 2 --text \"- Check running NFS daemon\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        else\n            LogText \"Output: NFS daemon is running\"\n            Display --indent 2 --text \"- Check running NFS daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n            NFS_DAEMON_RUNNING=1\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : STRG-1924\n    # Description : Check missing nfs in rpcinfo while NFS is running\n    #Register --test-no STRG-1924 --weight L --network NO --category security --description \"Checking NFS daemon\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n#\n#################################################################################\n#\n    # Test        : STRG-1926\n    # Description : Check NFS exports\n    if [ ${NFS_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no STRG-1926 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking NFS exports\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: check /etc/exports\"\n        if [ -f ${ROOTDIR}etc/exports ]; then\n            LogText \"Result: ${ROOTDIR}etc/exports exists\"\n            FIND=$(${GREPBINARY} -v \"^$\" ${ROOTDIR}etc/exports | ${GREPBINARY} -v \"^#\" | ${SEDBINARY} 's/ /!space!/g')\n            if [ -n \"${FIND}\" ]; then\n                for I in ${FIND}; do\n                    I=$(echo ${I} | ${SEDBINARY} 's/!space!/ /g')\n                    LogText \"Found line: ${I}\"\n                done\n            else\n                LogText \"Result: ${ROOTDIR}etc/exports does not contain exported file systems\"\n                NFS_EXPORTS_EMPTY=1\n            fi\n            Display --indent 4 --text \"- Checking ${ROOTDIR}etc/exports\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: file /etc/exports does not exist\"\n            Display --indent 4 --text \"- Checking ${ROOTDIR}etc/exports\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : STRG-1928\n    # Description : Check for empty exports file while NFS is running\n    if [ ${NFS_DAEMON_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no STRG-1928 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking empty /etc/exports\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${NFS_EXPORTS_EMPTY} -eq 1 ]; then\n            Display --indent 6 --text \"- Checking empty /etc/exports\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n            LogText \"Result: ${ROOTDIR}etc/exports seems to have no exported file systems\"\n            ReportSuggestion \"${TEST_NO}\" \"/etc/exports has no exported file systems, while NFS daemon is running. Check if NFS needs to run on this system\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : STRG-1930\n    # Description : Check client access to nfs share\n    if [ ${NFS_DAEMON_RUNNING} -eq 1 -a ${NFS_EXPORTS_EMPTY} -eq 0 -a ! \"${SHOWMOUNTBINARY}\" = \"\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no STRG-1930 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check client access to nfs share\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        sFIND=$(${SHOWMOUNTBINARY} -e | ${AWKBINARY} '{ print $2 }' | ${SEDBINARY} '1d' | ${GREPBINARY} \"\\*\")\n        if [ -n \"${sFIND}\" ]; then\n            LogText \"Result: all client are allowed to access a NFS share in /etc/exports\"\n            Display --indent 4 --text \"- Checking NFS client access\" --result \"ALL CLIENTS\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Specify clients that are allowed to access a NFS share /etc/exports\"\n            AddHP 2 3\n        else\n            LogText \"Result: only some clients are allowed to access a NFS share\"\n            Display --indent 4 --text \"- Checking NFS client access\" --result \"${STATUS_OK}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_system_integrity",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com/\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    AIDECONFIG=\"\"\n    CSF_CONFIG=\"${ROOTDIR}etc/csf/csf.conf\"\n    FILE_INT_TOOL=\"\"\n    FILE_INT_TOOL_FOUND=0     # Boolean, file integrity tool found\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_SYSTEM_INTEGRITY}\"\n    Display --indent 2 --text \"- Checking file integrity tools\"\n#\n#################################################################################\n#\n    # Test        : SINT-7010\n    # Description : System Integrity Status\n    if [ -x ${ROOTDIR}/usr/bin/csrutil ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; SKIPREASON=\"No CSrutil binary found\"; fi\n    Register --test-no SINT-7010 --os MacOS --preqs-met ${PREQS_MET} --skip-reason \"${SKIPREASON}\" --weight H --network NO --category security --description \"System Integrity Status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if ${ROOTDIR}usr/bin/csrutil status | ${GREPBINARY} -sq enabled ; then\n            Display --indent 2 --text \"- System Integrity Protection (status)\" --result \"${STATUS_OK}\" --color GREEN\n            Report \"system_integrity_tool[]=mac-sip\"\n            LogText \"Result: SIP enabled, OK\"\n            AddHP 3 3\n        else\n            Display --indent 2 --text \"- System Integrity Protection (status)\" --result \"${STATUS_NO}\" --color RED\n            LogText \"Result: SIP disabled, BAD\"\n            AddHP 0 3\n        fi\n    fi\n\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n# EOF\n"
  },
  {
    "path": "include/tests_time",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Time\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_TIME_AND_SYNCHRONIZATION}\"\n#\n#################################################################################\n#\n    CRON_DIRS=\"${ROOTDIR}etc/cron.d ${ROOTDIR}etc/cron.hourly ${ROOTDIR}etc/cron.daily ${ROOTDIR}etc/cron.weekly ${ROOTDIR}etc/cron.monthly ${ROOTDIR}var/spool/crontabs\"\n    CHRONY_CONF_FILE=\"\"\n    NTP_DAEMON=\"\"\n    NTP_DAEMON_RUNNING=0\n    NTP_CONFIG_FOUND=0\n    NTP_CONFIG_TYPE_DAEMON=0\n    NTP_CONFIG_TYPE_SCHEDULED=0\n    NTP_CONFIG_TYPE_EVENTBASED=0\n    NTP_CONFIG_TYPE_STARTUP=0\n    NTPD_RUNNING=0 # Specific for ntpd\n    OPENNTPD_COMMUNICATION=0 # if ntpctl can communicate\n    SYSTEMD_NTP_ENABLED=0\n#\n#################################################################################\n#\n    # Test        : TIME-3104\n    # Description : Check for a running NTP daemon\n    if [ -f /sys/hypervisor/type ]; then\n        # TODO: Skip NTP tests if we are in a DomU xen instance\n        FIND=$(cat /sys/hypervisor/type)\n        if [ \"${FIND}\" = \"xen\" ]; then PREQS_MET=\"NO\"; else PREQS_MET=\"YES\"; fi\n    elif [ -f /sbin/sysctl ] && [ \"$(/sbin/sysctl -n security.jail.jailed 2>/dev/null || echo 0)\" -eq 1 ]; then\n        # Skip NTP tests if we're in a FreeBSD jail\n        PREQS_MET=\"NO\"\n    else\n        PREQS_MET=\"YES\"\n    fi\n    Register --test-no TIME-3104 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for running NTP daemon or client\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Linux/FreeBSD (ntpdate), OpenBSD (ntpd, rdate), Chrony, systemd-timesyncd\n        LogText \"Test: Searching for a running NTP daemon or available client\"\n        FOUND=0\n\n        SEARCH_FILES=\"${ROOTDIR}etc/chrony.conf ${ROOTDIR}etc/chrony/chrony.conf\"\n        for FILE in ${SEARCH_FILES}; do\n            if [ -f ${FILE} ]; then LogText \"result: found chrony configuration: ${FILE}\"; CHRONY_CONF_FILE=\"${FILE}\"; fi\n        done\n        if [ -n \"${CHRONY_CONF_FILE}\" ]; then\n            if IsRunning \"chronyd\"; then\n                FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON=\"chronyd\"\n                Display --indent 2 --text \"- NTP daemon found: chronyd\" --result \"${STATUS_FOUND}\" --color GREEN\n            else\n                LogText \"Result: found chrony configuration, but no running daemon\"\n            fi\n        else\n            LogText \"Result: no chrony configuration found\"\n        fi\n\n        # Check time daemon (eg DragonFly BSD)\n        if IsRunning \"dntpd\"; then\n            FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON=\"dntpd\"\n            Display --indent 2 --text \"- NTP daemon found: dntpd\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        # Check for OpenNTPD, ntpctl comes with a \"regular\" install\n        if [ -n \"${NTPCTLBINARY}\" ]; then\n            # In contrast to timectl, \"synchronised: yes\" is not grepped.\n            # Reason: openntpd syncs only if large time corrections are not required or -s is passed.\n            #         This might be not intended by the administrator (-s is NOT the default!)\n            FIND=$(${PSBINARY} ax | ${GREPBINARY} \"ntpd: ntp engine\" | ${GREPBINARY} -v \"grep\")\n            # Status code 0 is when communication over the socket is successful\n            if ${NTPCTLBINARY} -s status > /dev/null 2> /dev/null; then\n                FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON=\"openntpd\"\n                LogText \"result: found openntpd (method: ntpctl)\"\n                OPENNTPD_COMMUNICATION=1\n            elif [ -n \"${FIND}\" ] ; then\n                # Reasons for ntpctl to fail might be someone spawned a new process thus overwriting the socket,\n                # then ended it, but another openntpd process is still running\n                FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON=\"openntpd\"\n                LogText \"result: found openntpd (method: ps)\"\n            else\n                LogText \"result: running openntpd not found, but ntpctl is installed\"\n            fi\n\n            if [ \"${NTP_DAEMON}\" = \"openntpd\" ]; then\n                Display --indent 2 --text \"- NTP daemon found: OpenNTPD\" --result \"${STATUS_FOUND}\" --color GREEN\n            fi\n        fi\n\n        # Check running processes (ntpd from ntp.org)\n        # As checking by process name is ambiguous (openntpd has the same process name),\n        # this check will be skipped if openntpd has been found.\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} \"ntpd\" | ${GREPBINARY} -v \"dntpd\" | ${GREPBINARY} -v \"ntpd: \" | ${GREPBINARY} -v \"grep\")\n        if [ \"${NTP_DAEMON}\" != \"openntpd\" ] && [  -n \"${FIND}\" ]; then\n            FOUND=1; NTPD_RUNNING=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1\n            NTP_DAEMON=\"ntpd\"\n            LogText \"Result: found running NTP daemon in process list\"\n            Display --indent 2 --text \"- NTP daemon found: ntpd\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        # Check time daemon (eg NetBSD)\n        if IsRunning \"timed\"; then\n            FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON=\"timed\"\n            Display --indent 2 --text \"- NTP daemon found: timed\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        # Check timedate daemon (systemd)\n        FIND=$(${PSBINARY} ax | ${GREPBINARY} \"systemd-timesyncd\" | ${GREPBINARY} -v \"grep\")\n        if [  -n \"${FIND}\" ]; then\n            FOUND=1; NTP_DAEMON_RUNNING=1; NTP_CONFIG_TYPE_DAEMON=1; NTP_DAEMON=\"systemd-timesyncd\"\n            Display --indent 2 --text \"- NTP daemon found: systemd (timesyncd)\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found running systemd-timesyncd in process list\"\n        fi\n\n        # Check crontab for OpenBSD/FreeBSD\n        # Check anacrontab for Linux\n        CRONTAB_FILES=\"/etc/anacrontab /etc/crontab\"\n        # Regex for matching multiple time synchronisation binaries\n        # Partial sanity check for sntp and ntpdig, but this does not consider all corner cases\n        CRONTAB_REGEX='ntpdate|rdate|sntp.+-(s|j|--adj)|ntpdig.+-(S|s)'\n        for I in ${CRONTAB_FILES}; do\n            if [ -f ${I} ]; then\n                LogText \"Test: checking for ntpdate, rdate, sntp or ntpdig in crontab file ${I}\"\n                FIND=$(${GREPBINARY} -E \"${CRONTAB_REGEX}\" ${I} | ${GREPBINARY} -v '^#')\n                if [ -n \"${FIND}\" ]; then\n                    FOUND=1; NTP_CONFIG_TYPE_SCHEDULED=1\n                    Display --indent 2 --text \"- Checking NTP client in crontab file (${I})\" --result \"${STATUS_FOUND}\" --color GREEN\n                    LogText \"Result: found ntpdate, rdate, sntp or ntpdig reference in crontab file ${I}\"\n                else\n                    #Display --indent 2 --text \"- Checking NTP client in crontab file (${I})\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n                    LogText \"Result: no ntpdate, rdate, sntp or ntpdig reference found in crontab file ${I}\"\n                fi\n            else\n                LogText \"Result: crontab file ${I} not found\"\n            fi\n        done\n\n        # Notes: only test for normal files. File /etc/cron.d/FIFO on solaris is a special file and test may hang\n        # Linux systems may have a .placeholder file\n        FOUND_IN_CRON=0\n\n        # Check cron jobs\n        for I in ${CRON_DIRS}; do\n            for J in \"${I}\"/*; do  # iterate over folders in a safe way\n                # Check: regular file, readable and not called .placeholder\n                FIND=$(echo \"${J}\" | ${GREPBINARY} -E '/.placeholder$')\n                if [ -f \"${J}\" ] && [ -r \"${J}\" ] && [ -z \"${FIND}\" ]; then\n                    LogText \"Test: checking for ntpdate, rdate, sntp or ntpdig in ${J}\"\n                    FIND=$(\"${GREPBINARY}\" -E \"${CRONTAB_REGEX}\" \"${J}\" | \"${GREPBINARY}\" -v \"^#\")\n                    if [ -n \"${FIND}\" ]; then\n                        FOUND=1; FOUND_IN_CRON=1; NTP_CONFIG_TYPE_SCHEDULED=1\n                        LogText \"Result: found ntpdate, rdate, sntp or ntpdig in ${J}\"\n                    fi\n                fi\n            done\n        done\n\n        if [ ${FOUND_IN_CRON} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking NTP client in cron files\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: found ntpdate or rdate in cron directory\"\n        else\n            LogText \"Result: no ntpdate or rdate found in cron directories\"\n        fi\n\n        # Checking if ntpdate is performed by event\n        LogText \"Test: checking for file /etc/network/if-up.d/ntpdate\"\n        if [ -f /etc/network/if-up.d/ntpdate ]; then\n            LogText \"Result: found ntpdate action when network interface comes up\"\n            FOUND=1\n            NTP_CONFIG_TYPE_EVENTBASED=1\n            Display --indent 2 --text \"- Checking event based ntpdate (if-up)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: file /etc/network/if-up.d/ntpdate does not exist\"\n        fi\n\n        # Configuration file for *BSD\n        if [ -f /etc/rc.conf ]; then\n            LogText \"Test: Checking if ntpdate is enabled at startup in *BSD\"\n            FIND=$(${GREPBINARY} 'ntpdate_enable=\"YES\"' /etc/rc.conf)\n            if [ -n \"${FIND}\" ]; then\n                LogText \"Result: ntpdate is enabled in rc.conf\"\n                FOUND=1\n                NTP_CONFIG_TYPE_STARTUP=1\n                # Only show suggestion when ntpdate is enabled, however ntpd is not running\n                if [ ${NTP_DAEMON_RUNNING} -eq 0 ]; then\n                    ReportSuggestion \"${TEST_NO}\" \"Although ntpdate is enabled in rc.conf, it is advised to run it at least daily or use a NTP daemon\"\n                fi\n            else\n                LogText \"Result: ntpdate is not enabled in rc.conf\"\n            fi\n        fi\n\n        if [ ${FOUND} -eq 0 ]; then\n            if [ ${ISVIRTUALMACHINE} -eq 1 ]; then\n                LogText \"Result: Skipping display warning, as virtual machines usually don't need time synchronization in the VM itself\"\n            else\n                Display --indent 2 --text \"- Checking for a running NTP daemon or client\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: Could not find a NTP daemon or client\"\n                ReportSuggestion \"${TEST_NO}\" \"Use NTP daemon or NTP client to prevent time issues.\"\n                AddHP 0 2\n            fi\n        else\n            Display --indent 2 --text \"- Checking for a running NTP daemon or client\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: Found a time syncing daemon/client.\"\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3106\n    # Description : Check status of systemd time synchronization\n    if [ ${SYSTEMD_NTP_ENABLED} -eq 1 -a -n \"${TIMEDATECTL}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3106 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check systemd NTP time synchronization status\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Check the status of time synchronization via timedatectl\"\n        FIND=$(${TIMEDATECTL} status | ${GREPBINARY} -E \"(NTP|System clock) synchronized: yes\")\n        if [ -z \"${FIND}\" ]; then\n            LogText \"Result: time not synchronized via NTP\"\n            ReportSuggestion \"${TEST_NO}\" \"Check timedatectl output. Synchronization via NTP is enabled, but status reflects it is not synchronized\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3112\n    # Description : Check for valid associations from ntpq peers list\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3112 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check active NTP associations ID's\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking for NTP association ID's from ntpq peers list\"\n        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} \"No association ID's returned\")\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking valid association ID's\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found one or more association ID's\"\n        else\n            Display --indent 2 --text \"- Checking valid association ID's\" --result \"${STATUS_WARNING}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Check ntp.conf for properly configured NTP servers and a correctly functioning name service.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3116\n    # Description : Check for stratum 16 peers\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3116 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check peers with stratum value of 16\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        COUNT=0\n        LogText \"Test: Checking stratum 16 sources from ntpq peers list\"\n        FIND=$(${NTPQBINARY} -p -n | ${AWKBINARY} '{ if ($2!=\".POOL.\" && $3==\"16\") { print $1 }}')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking high stratum ntp peers\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: All peers are lower than stratum 16\"\n        else\n            for ITEM in ${FIND}; do\n                LogText \"Found stratum 16 peer: ${ITEM}\"\n                FIND2=$(${GREPBINARY} -E \"^ntp-ignore-stratum-16-peer=${ITEM}\" ${PROFILE})\n                if IsEmpty \"${FIND2}\"; then\n                    COUNT=$((COUNT + 1))\n                    Report \"ntp_stratum_16_peer[]=${ITEM}\"\n                else\n                    LogText \"Output: host ${ITEM} ignored by profile\"\n                fi\n            done\n            # Check if one or more high stratum time servers are found\n            if [ ${COUNT} -eq 0 ]; then\n                Display --indent 2 --text \"- Checking high stratum ntp peers\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: all non local servers are lower than stratum 16, or whitelisted within the scan profile\"\n            else\n                Display --indent 2 --text \"- Checking high stratum ntp peers\" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: Found ${COUNT} high stratum (16) peers)\"\n                ReportSuggestion \"${TEST_NO}\" \"Check ntpq peers output for stratum 16 peers\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3120\n    # Description : Check unreliable peers from peer list\n    # Notes       : Items with # are too far away (network distance)\n    #               Items with - are not chosen due clustering algorithm\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3120 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check unreliable NTP peers\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking unreliable ntp peers\"\n        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} -E \"^(-|#)\" | ${AWKBINARY} '{ print $1 }' | ${SEDBINARY} 's/^-//g')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking unreliable ntp peers\" --result \"${STATUS_NONE}\" --color GREEN\n            LogText \"Result: No unreliable peers found\"\n        else\n            Display --indent 2 --text \"- Checking unreliable ntp peers\" --result \"${STATUS_FOUND}\" --color YELLOW\n            LogText \"Result: Found one or more unreliable peers (marked with a minus or dash sign)\"\n            for I in ${FIND}; do\n                LogText \"Unreliable peer: ${I}\"\n                Report \"ntp_unreliable_peer[]=${I}\"\n            done\n            ReportSuggestion \"${TEST_NO}\" \"Check ntpq peers output for unreliable ntp peers and correct/replace them\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3124\n    # Description : Check selected time source\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3124 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check selected time source\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking selected time source\"\n        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} '^*' | ${AWKBINARY} '{ if ($4==\"l\") { print $1 } }')\n        FIND2=$(${NTPQBINARY} -p -n | ${GREPBINARY} '^*' | ${AWKBINARY} '{ print $1 }')\n        if [ -z \"${FIND}\" -a -n \"${FIND2}\" ]; then\n            Display --indent 2 --text \"- Checking selected time source\" --result \"${STATUS_OK}\" --color GREEN\n            FIND2=$(echo ${FIND2} | ${SEDBINARY} 's/*//g')\n            LogText \"Result: Found selected time source (value: ${FIND2})\"\n        else\n            Display --indent 2 --text \"- Checking selected time source\" --result \"${STATUS_WARNING}\" --color RED\n            LogText \"Result: Found local source as selected time source. This could indicate that no external sources are available to sync with.\"\n            LogText \"Local source: ${FIND}\"\n            ReportSuggestion \"${TEST_NO}\" \"Check ntpq peers output for selected time source\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3128\n    # Description : Check time source candidates\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3128 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check preferred time source\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking preferred time source\"\n        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} '^+' | ${AWKBINARY} '{ print $1 }')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking time source candidates\" --result \"${STATUS_NONE}\" --color YELLOW\n            LogText \"Result: No other time source candidates found\"\n            ReportSuggestion \"${TEST_NO}\" \"Check ntpq peers output for time source candidates\"\n        else\n            Display --indent 2 --text \"- Checking time source candidates\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: Found one or more candidates to synchronize time with.\"\n            for I in ${FIND}; do\n                I=$(echo ${I} | ${SEDBINARY} 's/+//g')\n                LogText \"Candidate found: ${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3132\n    # Description : Check ntpq falsetickers\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3132 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check NTP falsetickers\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking preferred time source\"\n        FIND=$(${NTPQBINARY} -p -n | ${GREPBINARY} -E '^x')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking falsetickers\" --result \"${STATUS_OK}\" --color GREEN\n            LogText \"Result: No falsetickers found (items preceding with an 'x')\"\n        else\n            Display --indent 2 --text \"- Checking falsetickers\" --result \"${STATUS_NONE}\" --color YELLOW\n            LogText \"Result: Found one or more falsetickers  (items preceding with an 'x')\"\n            for I in ${FIND}; do\n                I=$(echo ${I} | ${SEDBINARY} 's/x//g')\n                LogText \"Falseticker found: ${I}\"\n                Report \"ntp_falseticker[]=${I}\"\n            done\n            ReportSuggestion \"${TEST_NO}\" \"Check ntpq peers output for falsetickers\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3136\n    # Description : Check ntpq reported ntp version (Linux)\n    if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3136 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check NTP protocol version\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking NTP protocol version (ntpq -c ntpversion)\"\n        FIND=$(${NTPQBINARY} -c ntpversion | ${AWKBINARY} '{ if ($1==\"NTP\" && $2==\"version\" && $5==\"is\") { print $6 } }')\n        if [ -z \"${FIND}\" ]; then\n            Display --indent 2 --text \"- Checking NTP version\" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n            LogText \"Result: No NTP version found\"\n            ReportSuggestion \"${TEST_NO}\" \"Check ntpq output for NTP protocol version\"\n        else\n            Display --indent 2 --text \"- Checking NTP version\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: Found NTP version ${FIND}\"\n            Report \"ntp_version=${FIND}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3146\n    # Description : Check /etc/default/ntpdate (Linux)\n    # Notes       : ntpdate-debian binary\n    #if [ ${NTPD_RUNNING} -eq 1 -a -n \"${NTPQBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    #Register --test-no TIME-3146 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check /etc/default/ntpdate\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n#\n#################################################################################\n#\n    # Test        : TIME-3148\n    # Description : Check if TZ variable is set (Linux)\n    # Notes       : without TZ variable set, a lot of unneeded calls might be performed.\n    Register --test-no TIME-3148 --os Linux --weight L --network NO --category performance --description \"Check TZ variable\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: testing for TZ variable\"\n        FIND=\"${TZ:=notset}\"\n        LogText \"Result: found TZ variable with value ${FIND}\"\n        if [ \"${FIND}\" = \"notset\" ]; then\n            Report \"tz_variable_empty=1\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3160\n    # Description : Check empty NTP step-tickers\n    # Notes       : Mostly applies to Red Hat and clones\n    FILE=\"${ROOTDIR}etc/ntp/step-tickers\"\n    if [ \"${NTPD_RUNNING}\" -eq 1 -a -n \"${NTPQBINARY}\" -a -f \"${FILE}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TIME-3160 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check empty NTP step-tickers\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        OUTPUT=$(${AWKBINARY} '/^[a-z0-9]/ { print $1 }' ${FILE})\n        if [ -z \"${OUTPUT}\" ]; then\n            if [ ${OS_REDHAT_OR_CLONE} -eq 1 -a -f \"${FILE}\" ]; then\n                # On RedHat if step-ticker file exists but is empty, the ntpdate start script uses the servers listed in ntp.conf for the initial time synchronization\n                LogText \"Result: ${FILE} exists and it is empty. On RedHat the initial time synchronization will be done with the servers listed in ntp.conf.\"\n                Display --indent 2 --text \"- Checking NTP step-tickers file\" --result \"${STATUS_OK}\" --color GREEN\n            else\n                LogText \"Result: ${FILE} is empty. The step-tickers contain no configured NTP servers\"\n                Display --indent 2 --text \"- Checking NTP step-tickers file\" --result \"EMPTY FILE\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Use step-tickers file for quicker time synchronization\"\n            fi\n        else\n            LogText \"Result: ${FILE} is not empty, which is fine\"\n            Display --indent 2 --text \"- Checking NTP step-tickers file\" --result \"${STATUS_OK}\" --color GREEN\n            sFIND=$(${AWKBINARY} '/^[a-z0-9]/ { print $1 }' ${FILE} | ${GREPBINARY} -E -v \"^127.\" | ${GREPBINARY} -E -v \"^::1\")\n            for I in ${sFIND}; do\n                FIND=$(${GREPBINARY} ^${I} ${FILE} | wc -l)\n                if [ ${FIND} -gt 0 ]; then\n                    LogText \"Result: $I exist in ${FILE}\"\n                else\n                    LogText \"Result: ${I} does NOT exist in ${FILE}\"\n                    FOUND=1\n                fi\n            done\n            if [ ${FOUND} -eq 1 ]; then\n                Display --indent 4 --text \"- Checking step-tickers ntp servers entries\" --result \"SOME MISSING\" --color YELLOW\n                ReportSuggestion \"${TEST_NO}\" \"Some time servers missing in step-tickers file\"\n                AddHP 3 4\n            else\n                Display --indent 4 --text \"- Checking step-tickers ntp servers entries\" --result \"${STATUS_OK}\" --color GREEN\n                LogText \"Result: all time servers are in step-tickers file\"\n                AddHP 4 4\n            fi\n        fi\n        LogText \"Information: step-tickers is used by ntpdate where as ntp.conf is the configuration file for the ntpd daemon. ntpdate is initially run to set the clock before ntpd to make sure time is within 1000 sec.\"\n        LogText \"Risk: ntp will not run at boot if the time difference between the server and client by more then 1000 sec.\"\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3170\n    # Description : Check file permissions and ownership of configuration files\n    # Notes       : Files should be owned by root, or the user running\n    #               Group owner should have only read access\n    #               Other should preferably have no access, or read-only at max\n\n    FILE_ARRAY=\"${ROOTDIR}etc/chrony.conf ${ROOTDIR}usr/pkg/etc/chrony.conf \\\n        ${ROOTDIR}etc/inet/ntp.conf ${ROOTDIR}etc/ntp.conf ${ROOTDIR}usr/local/etc/ntp.conf\\\n        ${ROOTDIR}etc/ntpd.conf ${ROOTDIR}etc/openntpd/ntpd.conf ${ROOTDIR}usr/local/etc/ntpd.conf\"\n\n    Register --test-no TIME-3170 --weight L --network NO --category security --description \"Check configuration files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for FILE in ${FILE_ARRAY}; do\n            if [ -f ${FILE} ]; then\n                LogText \"Result: found ${FILE}\"\n                if IsWorldWritable ${FILE}; then\n                    ReportWarning \"${TEST_NO}\" \"Found world writable configuration file\" \"${FILE}\" \"\"\n                fi\n                Report \"ntp_config_file[]=${FILE}\"\n                NTP_CONFIG_FOUND=1\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3180\n    # Description : Report if ntpctl cannot communicate with OpenNTPD\n    if [ \"${NTP_DAEMON_RUNNING}\" -eq 1 ] && [ -n \"${NTPCTLBINARY}\" ] && [ \"${NTP_DAEMON}\" = \"openntpd\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n    Register --test-no TIME-3180 --preqs-met \"${PREQS_MET}\" --weight L --network NO --category security --description \"Report if ntpctl cannot communicate with OpenNTPD\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ \"${OPENNTPD_COMMUNICATION}\" -eq 0 ]; then\n            ReportWarning \"${TEST_NO}\" \"OpenNTPD found, but ntpctl cannot communicate with\" \"${NTPCTLBINARY} -s status\" \"Restart OpenNTPD\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3181\n    # Description : Check status of OpenNTPD time synchronisation\n    if [ \"${NTP_DAEMON_RUNNING}\" -eq 1 ] && [ -n \"${NTPCTLBINARY}\" ] && [ \"${NTP_DAEMON}\" = \"openntpd\" ] && [ \"${OPENNTPD_COMMUNICATION}\" -eq 1 ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    Register --test-no TIME-3181 --preqs-met \"${PREQS_MET}\" --weight L --network NO --category security --description \"Check status of OpenNTPD time synchronisation\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${NTPCTLBINARY} -s status | ${GREPBINARY} \"clock synced\" )\n        if [ -z \"${FIND}\" ]; then\n            ReportWarning \"${TEST_NO}\" \"OpenNTPD is not synchronising system time\" \"${NTPCTLBINARY} -s status\" \"text:Set time manually once or check network connectivity.\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TIME-3182\n    # Description : Check OpenNTPD has working peers\n\n    if [ \"${NTP_DAEMON_RUNNING}\" -eq 1 ] && [ -n \"${NTPCTLBINARY}\" ] && [ \"${NTP_DAEMON}\" = \"openntpd\" ] && [ \"${OPENNTPD_COMMUNICATION}\" -eq 1 ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n    Register --test-no TIME-3182 --preqs-met \"${PREQS_MET}\" --weight L --network NO --category security --description \"Check OpenNTPD has working peers\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Format is \"xx/yy peers valid, ...\"\n        FIND=$(${NTPCTLBINARY} -s status | ${GREPBINARY} -E -o '[0-9]+/[0-9]+' | ${CUTBINARY} -d '/' -f 1)\n        if [ -z \"${FIND}\" ] || [ \"${FIND}\" -eq 0 ]; then\n            ReportWarning \"${TEST_NO}\" \"OpenNTPD has no peers\" \"${NTPCTLBINARY} -s status\"\n        fi\n    fi\n\n#\n#################################################################################\n#\n\n    # Test        : TIME-3185\n    # Description : Check systemd-timesyncd synchronized time\n\n    if [ \"${NTP_DAEMON}\" = \"systemd-timesyncd\" ]; then\n        PREQS_MET=\"YES\"\n    else\n        PREQS_MET=\"NO\"\n    fi\n\n\n    Register --test-no TIME-3185 --preqs-met \"${PREQS_MET}\" --weight L --network NO --category \"security\" --description \"Check systemd-timesyncd synchronized time\"\n    SYNCHRONIZED_FILE=\"/run/systemd/timesync/synchronized\"\n       \n    if [ ${SKIPTEST} -eq 0 ]; then\n        # On earlier systemd versions (237), '/run/systemd/timesync/synchronized' does not exist, so use '/var/lib/systemd/timesync/clock'\n        if [ ! -e \"${SYNCHRONIZED_FILE}\" ]; then\n            SYNCHRONIZED_FILE=\"/var/lib/systemd/timesync/clock\"\n        fi\n        # DynamicUser=yes moves the clock file to '/var/lib/private/systemd/timesync/clock'\n        if [ ! -e \"${SYNCHRONIZED_FILE}\" ]; then\n            SYNCHRONIZED_FILE=\"/var/lib/private/systemd/timesync/clock\"\n        fi\n        # Fix for debian stretch\n        if [ ! -e \"${SYNCHRONIZED_FILE}\" ]; then\n            SYNCHRONIZED_FILE=\"/var/lib/systemd/clock\"\n        fi\n        if [ -e \"${SYNCHRONIZED_FILE}\" ]; then\n           FIND=$(( $(date +%s) - $(${STATBINARY} -L --format %Y \"${SYNCHRONIZED_FILE}\") ))\n           # Check if last sync was more than 2048 seconds (= the default of systemd) ago\n           if [ \"${FIND}\" -ge 2048 ]; then\n               COLOR=RED\n               ReportWarning \"${TEST_NO}\" \"systemd-timesyncd did not synchronized the time recently.\"\n           else\n               COLOR=GREEN\n           fi\n           Display --indent 2 --text \"- Last time synchronization\" --result \"${FIND}s\" --color \"${COLOR}\"\n           LogText \"Result: systemd-timesyncd synchronized time ${FIND} seconds ago.\"\n        else\n           Display --indent 2 --text \"- Last time synchronization\" --result \"${STATUS_NOT_FOUND}\" --color RED\n           ReportWarning \"${TEST_NO}\" \"systemd-timesyncd never successfully synchronized time\"\n        fi\n    fi\n    unset SYNCHRONIZED_FILE\n\n#\n#################################################################################\n#\n\n    Report \"ntp_config_found=${NTP_CONFIG_FOUND}\"\n    Report \"ntp_config_type_daemon=${NTP_CONFIG_TYPE_DAEMON}\"\n    Report \"ntp_config_type_eventbased=${NTP_CONFIG_TYPE_EVENTBASED}\"\n    Report \"ntp_config_type_scheduled=${NTP_CONFIG_TYPE_SCHEDULED}\"\n    Report \"ntp_config_type_startup=${NTP_CONFIG_TYPE_STARTUP}\"\n    Report \"ntp_daemon=${NTP_DAEMON}\"\n    Report \"ntp_daemon_running=${NTP_DAEMON_RUNNING}\"\n#\n#################################################################################\n#\n    # For VMs check ntpd.conf : tinker panic 0\n\n    # OS        Time daemons  Configuration file\n    # --------------------------------------------\n    # AIX       xntpd         /etc/ntp.conf\n    # HP\n    # Linux     ntpd          /etc/ntp.conf\n    #           chrony        /etc/chrony.conf\n    # OpenBSD   ntpd          /etc/ntpd.conf\n    # Solaris   xntpd         /etc/inet/ntp.conf\n\n    WaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_tooling",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n    ANSIBLE_ARTIFACT_FOUND=0\n    AUTOMATION_TOOL_FOUND=0\n    AUTOMATION_TOOL_RUNNING=\"\"\n    CFENGINE_AGENT_FOUND=0\n    CFENGINE_SERVER_RUNNING=0\n    BACKUP_AGENT_FOUND=0\n    PUPPET_MASTER_RUNNING=0\n    SALT_MASTER_RUNNING=0\n    SALT_MINION_RUNNING=0\n    IDS_IPS_TOOL_FOUND=0\n    FAIL2BAN_FOUND=0\n    FAIL2BAN_EMAIL=0\n    FAIL2BAN_SILENT=0\n    PERFORM_FAIL2BAN_TESTS=0\n    SNORT_FOUND=0\n    SNORT_RUNNING=0\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_SYSTEM_TOOLING}\"\n#\n#################################################################################\n#\n# Automation\n#\n#################################################################################\n#\n    # Test        : TOOL-5002\n    # Description : Check if automation tools are found\n    Register --test-no TOOL-5002 --weight L --network NO --category security --description \"Checking for automation tools\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        Display --indent 2 --text \"- Checking automation tooling\"\n\n        # Ansible\n        FOUND=0\n        LIST=\"${HOME}/.ansible ${ROOTDIR}etc/ansible ${ROOTDIR}root/.ansible ${ROOTDIR}tmp/.ansible\"\n        for ITEM in ${LIST}; do if DirectoryExists ${ITEM}; then FOUND=1; break; fi; done\n        # Test for files (only if no match was found)\n        if [ ${FOUND} -eq 0 ]; then\n            LIST=\"${ROOTDIR}var/log/ansible.log ~/.ansible-retry\"\n            for ITEM in ${LIST}; do if FileExists ${ITEM}; then FOUND=1; break; fi; done\n        fi\n\n        if [ ${FOUND} -eq 1 ]; then\n            LogText \"Result: found a possible trace of Ansible\"\n            AUTOMATION_TOOL_FOUND=1\n            ANSIBLE_ARTIFACT_FOUND=1\n            Report \"automation_tool_running[]=ansible\"\n            Display --indent 4 --text \"- Ansible artifact\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        # Cfengine\n        if [ -n \"${CFAGENTBINARY}\" ]; then\n            LogText \"Result: CFEngine (cfagent) is installed (${CFAGENTBINARY})\"\n            AUTOMATION_TOOL_FOUND=1\n            CFENGINE_AGENT_FOUND=1\n            Report \"automation_tool_running[]=cf-agent\"\n            Display --indent 4 --text \"- Cfengine (cfagent)\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n        OTHER_CFENGINE_LOCATIONS=\"/var/cfengine/bin /var/rudder/cfengine-community/bin\"\n        for I in ${OTHER_CFENGINE_LOCATIONS}; do\n            if [ -d ${I} ]; then\n                if [ -f ${I}/cf-agent ]; then\n                    LogText \"Result: found CFEngine agent (cf-agent) in ${I}\"\n                    AUTOMATION_TOOL_FOUND=1\n                    CFENGINE_AGENT_FOUND=1\n                    Report \"automation_tool_running[]=cf-agent\"\n                    Display --indent 4 --text \"- CFEngine (cf-agent)\" --result \"${STATUS_FOUND}\" --color GREEN\n                fi\n                if IsRunning \"cf-server\"; then\n                    LogText \"Result: found CFEngine server\"\n                    AUTOMATION_TOOL_FOUND=1\n                    CFENGINE_SERVER_RUNNING=1\n                    Report \"automation_tool_running[]=cf-server\"\n                    Display --indent 4 --text \"- CFEngine (cf-server)\" --result \"${STATUS_FOUND}\" --color GREEN\n                fi\n            fi\n        done\n\n        # Chef\n        CHEF_LOCATIONS=\"/opt/chef/bin /opt/chef-server/sv /opt/chefdk/bin\"\n        for I in ${CHEF_LOCATIONS}; do\n            if [ -d ${I} ]; then\n                if [ -f ${I}/chef-client ]; then\n                    CHEFCLIENTBINARY=\"${I}/chef-client\"\n                    AUTOMATION_TOOL_FOUND=1\n                    Report \"automation_tool_running[]=chef-client\"\n                    Display --indent 4 --text \"- Chef client (chef-client)\" --result \"${STATUS_FOUND}\" --color GREEN\n                    LogText \"Result: found chef-client (chef client daemon) in ${I}\"\n                fi\n                if [ -f ${I}/erchef ]; then\n                    CHEFSERVERBINARY=\"${I}/erchef\"\n                    LogText \"Result: Chef Server (erchef) is installed (${CHEFSERVERBINARY})\"\n                    AUTOMATION_TOOL_FOUND=1\n                    Report \"automation_tool_running[]=chef-server\"\n                    Display --indent 4 --text \"- Chef Server (erchef)\" --result \"${STATUS_FOUND}\" --color GREEN\n                    LogText \"Result: found erchef (chef server daemon) in ${I}\"\n                fi\n            fi\n        done\n\n        # Puppet\n\n        # Check for Puppet installation provided by Puppetlabs package\n        if [ -z \"${PUPPETBINARY}\" ]; then\n            if [ -f ${ROOTDIR}opt/puppetlabs/puppet/bin/puppet ]; then\n                PUPPETBINARY=\"${ROOTDIR}opt/puppetlabs/puppet/bin/puppet\"\n            fi\n        fi\n\n        if [ -n \"${PUPPETBINARY}\" ]; then\n            LogText \"Result: Puppet is installed (${PUPPETBINARY})\"\n            AUTOMATION_TOOL_FOUND=1\n            Report \"automation_tool_running[]=puppet-agent\"\n            Display --indent 4 --text \"- Puppet (agent)\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        if IsRunning --full \"puppet master\"; then\n            LogText \"Result: found puppet master\"\n            AUTOMATION_TOOL_FOUND=1\n            PUPPET_MASTER_RUNNING=1\n            Report \"automation_tool_running[]=puppet-master\"\n            Display --indent 4 --text \"- Puppet (master)\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        # SaltStack\n        if [ -n \"${SALTMINIONBINARY}\" ]; then\n            Display --indent 4 --text \"- SaltStack minion\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: SaltStack (salt-minion) is installed (${SALTMINIONBINARY})\"\n            AUTOMATION_TOOL_FOUND=1\n            Report \"automation_tool_installed[]=saltstack-minion\"\n\n            if IsRunning \"salt-minion\" --user \"root salt\"; then\n                Display --indent 6 --text \"- Minion process\" --result \"${STATUS_RUNNING}\" --color GREEN\n                LogText \"Result: found SaltStack (master)\"\n                SALT_MINION_RUNNING=1\n                Report \"automation_tool_running[]=saltstack-minion\"\n            else\n                Display --indent 6 --text \"- Minion process\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW\n            fi\n\n        fi\n\n        if [ -n \"${SALTMASTERBINARY}\" ]; then\n            Display --indent 4 --text \"- SaltStack master (salt-master)\" --result \"${STATUS_FOUND}\" --color GREEN\n            LogText \"Result: SaltStack (salt-master) is installed (${SALTMASTERBINARY})\"\n            AUTOMATION_TOOL_FOUND=1\n            Report \"automation_tool_installed[]=saltstack-master\"\n\n            if IsRunning \"salt-master\" --user \"root salt\"; then\n                Display --indent 6 --text \"- Master process\" --result \"${STATUS_RUNNING}\" --color GREEN\n                LogText \"Result: found SaltStack (master)\"\n                SALT_MASTER_RUNNING=1\n                Report \"automation_tool_running[]=saltstack-master\"\n            else\n                Display --indent 6 --text \"- Master process\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW\n            fi\n        fi\n\n        if [ ${AUTOMATION_TOOL_FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Automation tooling\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            Display --indent 2 --text \"- Automation tooling\" --result \"${STATUS_NOT_FOUND}\" --color YELLOW\n            ReportSuggestion \"${TEST_NO}\" \"Determine if automation tools are present for system management\"\n        fi\n    fi\n#\n#################################################################################\n#\n# Intrusion Detection and Prevention tools\n#\n#################################################################################\n#\n    # Test        : TOOL-5102\n    # Description : Check for Fail2ban\n    Register --test-no TOOL-5102 --weight L --network NO --category security --description \"Check for presence of Fail2ban\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        # Fail2ban presence\n        if [ -n \"${FAIL2BANBINARY}\" ]; then\n            FAIL2BAN_FOUND=1\n            IDS_IPS_TOOL_FOUND=1\n            LogText \"Result: Fail2ban is installed (${FAIL2BANBINARY})\"\n            Report \"ids_ips_tooling[]=fail2ban\"\n            Display --indent 2 --text \"- Checking presence of Fail2ban\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: Fail2ban not present (fail2ban-server not found)\"\n        fi\n\n        # Fail2ban configuration\n        LogText \"Checking Fail2ban configuration file\"\n        if [ -f /etc/fail2ban/jail.local ]; then\n            FAIL2BAN_CONFIG=\"/etc/fail2ban/jail.local\"\n        elif [ -f /etc/fail2ban/jail.conf ]; then\n            FAIL2BAN_CONFIG=\"/etc/fail2ban/jail.conf\"\n        else\n            FAIL2BAN_CONFIG=\"\"\n        fi\n\n        # Continue if tooling is available and configuration file found\n        if [ ${FAIL2BAN_FOUND} -eq 1 -a -n \"${FAIL2BAN_CONFIG}\" ]; then\n            Report \"fail2ban_config=${FAIL2BAN_CONFIG}\"\n            FAIL2BANCLIENT=$(which fail2ban-client 2> /dev/null | grep -v \"no [^ ]* in \")\n            if [ -n \"${FAIL2BANCLIENT}\" ]; then PERFORM_FAIL2BAN_TESTS=1; fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5104\n    # Description : Check for Fail2ban enabled tests\n    if [ ${PERFORM_FAIL2BAN_TESTS} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no TOOL-5104 --weight L --network NO --preqs-met ${PREQS_MET} --category security --description \"Enabled tests in Fail2ban\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${FAIL2BANCLIENT} -d | ${TRBINARY} -d '[]' | ${TRBINARY} -d \"'\" | ${AWKBINARY} -F, '{ if ($1==\"add\") { print $2 }}' | ${TRBINARY} -d ' ')\n        if [ -n \"${FIND}\" ]; then\n            for F2BSERVICE in ${FIND}; do\n                LogText \"Result: service '${F2BSERVICE}' enabled\"\n                Report \"fail2ban_enabled_service[]=${F2BSERVICE}\"\n            done\n            LogText \"Result: found at least one enabled jail\"\n            Display --indent 4 --text \"- Checking Fail2ban jails\" --result \"${STATUS_ENABLED}\" --color GREEN\n            AddHP 3 3\n        else\n            LogText \"Result: Fail2ban installed but completely disabled\"\n            Display --indent 4 --text \"- Checking Fail2ban jails\" --result \"${STATUS_DISABLED}\" --color RED\n            AddHP 0 5\n            ReportWarning \"${TEST_NO}\" \"All jails in Fail2ban are disabled\" \"${FAIL2BAN_CONFIG}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # These tests are temporarily disabled to split them up in different areas to check\n    #\n    #            LogText \"Result: found configuration file (${FAIL2BAN_CONFIG})\"\n    #\n    #            # Check email alert configuration\n    #            LogText \"Test: checking for email actions within ${FAIL2BAN_CONFIG}\"\n    #\n    #            FIND=$(${GREPBINARY} -E \"^action = \\%\\(action_m.*\\)s\" ${FAIL2BAN_CONFIG})\n    #            FIND2=$(${GREPBINARY} -E \"^action = \\%\\(action_\\)s\" ${FAIL2BAN_CONFIG})\n    #\n    #            if [ -n \"${FIND}\" ]; then\n    #                FAIL2BAN_EMAIL=1\n    #                LogText \"Result: found at least one jail which sends an email alert\"\n    #            fi\n    #\n    #            if [ -n \"${FIND2}\" ]; then\n    #                FAIL2BAN_SILENT=1\n    #                LogText \"Result: found at least one jail which does NOT send an email alert\"\n    #            fi\n    #\n    #            if [ ${FAIL2BAN_SILENT} -eq 0 ] && [ ${FAIL2BAN_EMAIL} -eq 0 ]; then\n    #                LogText \"No registered actions found in ${FAIL2BAN_CONFIG}\"\n    #                Display --indent 4 --text \"- Checking Fail2ban actions\" --result \"${STATUS_NONE}\" --color RED\n    #                ReportWarning \"${TEST_NO}\" \"${FAIL2BAN_CONFIG}\" \"There are no actions configured for Fail2ban.\"\n    #                AddHP 0 3\n    #            fi\n    #\n    #            if [ ${FAIL2BAN_SILENT} -eq 0 ] && [ ${FAIL2BAN_EMAIL} -eq 1 ]; then\n    #                LogText \"All actions in ${FAIL2BAN_CONFIG} are configured to send email alerts\"\n    #                Display --indent 4 --text \"- Checking Fail2ban actions\" --result \"${STATUS_OK}\" --color GREEN\n    #                AddHP 3 3\n    #            fi\n    #\n    #            if [ ${FAIL2BAN_SILENT} -eq 1 ] && [ ${FAIL2BAN_EMAIL} -eq 1 ]; then\n    #                LogText \"Some actions found in ${FAIL2BAN_CONFIG} are configured to send email alerts\"\n    #                Display --indent 4 --text \"- Checking Fail2ban actions\" --result PARTIAL --color YELLOW\n    #                ReportSuggestion \"${TEST_NO}\" \"Some Fail2ban jails are configured with non-notified actions.  Consider changing these to emailed alerts.\"\n    #                AddHP 2 3\n    #            fi\n    #\n    #            if [ ${FAIL2BAN_SILENT} -eq 1 ] && [ ${FAIL2BAN_EMAIL} -eq 0 ]; then\n    #                LogText \"None of the actions found in ${FAIL2BAN_CONFIG} are configured to send email alerts\"\n    #                Display --indent 4 --text \"- Checking Fail2ban actions\" --result \"${STATUS_NONE}\" --color YELLOW\n    #                ReportSuggestion \"${TEST_NO}\" \"None of the Fail2ban jails are configured to send email notifications.  Consider changing these to emailed alerts.\"\n    #                AddHP 1 3\n    #            fi\n    #\n    #            # Check at least one enabled jail\n    #            LogText \"Checking for enabled jails within ${FAIL2BAN_CONFIG}\"\n    #\n    #\n    #\n    #            # Confirm at least one iptables chain for fail2ban\n    #\n    #            LogText \"Checking for fail2ban iptables chains\"\n    #\n    #            if [ -n \"${IPTABLESBINARY}\" ]; then\n    #                CHECK_CHAINS=$(${IPTABLESBINARY} -L 2>&1 | ${GREPBINARY} fail2ban)\n    #                if [ -n \"${CHECK_CHAINS}\" ]; then\n    #                    LogText \"Result: found at least one iptables chain for fail2ban\"\n    #                    Display --indent 4 --text \"- Checking for Fail2ban iptables chain\" --result \"${STATUS_OK}\" --color GREEN\n    #                else\n    #                    LogText \"Result: Fail2ban installed but iptables chain not present - fail2ban will not work\"\n    #                    Display --indent 4 --text \"- Checking for Fail2ban iptables chain\" --result \"${STATUS_WARNING}\" --color RED\n    #                    AddHP 0 3\n    #                    ReportSuggestion \"${TEST_NO}\" \"Check config to see why iptables does not have a fail2ban chain\" \"${FAIL2BAN_CONFIG}\"\n    #                fi\n    #            else\n    #                Display --indent 4 --text \"- Checking for Fail2ban iptables chain\" --result \"${STATUS_WARNING}\" --color RED\n    #                ReportSuggestion \"${TEST_NO}\" \"iptables doesn't seem to be installed; Fail2ban will not work. Remove Fail2ban or install iptables\" \"${FAIL2BAN_CONFIG}\"\n    #            fi\n    #        fi\n    #    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5120\n    # Description : Check for Snort\n    Register --test-no TOOL-5120 --weight L --network NO --category security --description \"Check for presence of Snort\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        # Snort presence\n        if [ -n \"${SNORTBINARY}\" ]; then\n            SNORT_FOUND=1\n            IDS_IPS_TOOL_FOUND=1\n            LogText \"Result: Snort is installed (${SNORTBINARY})\"\n            Report \"ids_ips_tooling[]=snort\"\n            Display --indent 2 --text \"- Checking presence of Snort\" --result \"${STATUS_FOUND}\" --color GREEN\n        fi\n\n        if IsRunning \"snort\"; then\n            SNORT_FOUND=1\n            SNORT_RUNNING=1\n            SNORT_LOG=$(${PSBINARY} | ${AWKBINARY} -F-.. '/snort/ {print $4}' | ${HEADBINARY} -1)\n        else\n            LogText \"Result: Snort not present (Snort not running)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5122\n    # Description : Check for Snort configuration\n    Register --test-no TOOL-5122 --weight L --network NO --category security --description \"Check Snort configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        # Continue if tooling is available and snort is running\n        if [ -n \"${SNORT_FOUND}\" ] || [ -n \"${SNORT_RUNNING}\" ]; then\n            if [ ${SNORT_FOUND} -eq 1 ] && [ ${SNORT_RUNNING} -eq 1 ]; then\n                SNORT_CONFIG=$(${PSBINARY} | ${AWKBINARY} -F-.. '/snort/ {print $3}' | ${HEADBINARY} -1)\n                if HasData \"${SNORT_CONFIG}\"; then\n                    LogText \"Result: found Snort configuration file: ${SNORT_CONFIG}\"\n                    Report \"snort_config=${SNORT_CONFIG}\"\n                fi\n                SNORT=$(which snort 2> /dev/null)\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5130\n    # Description : Check for Suricata\n    Register --test-no TOOL-5130 --weight L --network NO --category security --description \"Check for active Suricata daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Suricata presence\n        if [ -n \"${SURICATABINARY}\" ]; then\n            Report \"ids_ips_tooling[]=suricata\"\n            LogText \"Result: Suricata is installed (${SURICATABINARY})\"\n            # Suricata status\n            # Suricata sets its process name to Suricata-Main on Linux, but this might differ on other platforms,\n            # so fall back to checking the full commandline instead if the first test fails\n            if IsRunning \"Suricata-Main\" || IsRunning --full \"${SURICATABINARY} \"; then\n                # Only satisfy test TOOL-5190 if Suricata is actually running\n                IDS_IPS_TOOL_FOUND=1\n                LogText \"Result: Suricata daemon is active\"\n                Display --indent 2 --text \"- Checking Suricata status\" --result \"${STATUS_RUNNING}\" --color GREEN\n            else\n                LogText \"Result: Suricata daemon not active\"\n                Display --indent 2 --text \"- Checking Suricata status\" --result \"${STATUS_NOT_RUNNING}\" --color YELLOW\n            fi\n        else\n            LogText \"Result: Suricata not installed (suricata not found)\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5126\n    # Description : Check for OSSEC\n    Register --test-no TOOL-5126 --weight L --network NO --category security --description \"Check for active OSSEC daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Server side\n        if IsRunning \"ossec-analysisd\"; then\n            IDS_IPS_TOOL_FOUND=1\n            Report \"ids_ips_tooling[]=ossec\"\n            Report \"ids_ips_tooling[]=ossec-analysisd\"\n            LogText \"Result: OSSEC analysis daemon is active\"\n            Display --indent 2 --text \"- Checking presence of OSSEC (analysis)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: OSSEC analysis daemon not active\"\n        fi\n\n        # Client side\n        if IsRunning \"ossec-agentd\"; then\n            IDS_IPS_TOOL_FOUND=1\n            Report \"ids_ips_tooling[]=ossec\"\n            Report \"ids_ips_tooling[]=ossec-agentd\"\n            LogText \"Result: OSSEC agent daemon is active\"\n            Display --indent 2 --text \"- Checking presence of OSSEC (agent)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: OSSEC agent daemon not active\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5128\n    # Description : Check for Wazuh daemon\n    Register --test-no TOOL-5128 --weight L --network NO --category security --description \"Check for active Wazuh daemon\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Server side\n        if IsRunning \"wazuh-analysisd\"; then\n            IDS_IPS_TOOL_FOUND=1\n            Report \"ids_ips_tooling[]=wazuh\"\n            Report \"ids_ips_tooling[]=wazuh-analysisd\"\n            LogText \"Result: Wazuh analysis daemon is active\"\n            Display --indent 2 --text \"- Checking presence of Wazuh (analysis)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: Wazuh analysis daemon not active\"\n        fi\n\n        # Client side\n        if IsRunning \"wazuh-agentd\"; then\n            IDS_IPS_TOOL_FOUND=1\n            Report \"ids_ips_tooling[]=wazuh\"\n            Report \"ids_ips_tooling[]=wazuh-agentd\"\n            LogText \"Result: Wazuh agent daemon is active\"\n            Display --indent 2 --text \"- Checking presence of Wazuh (agent)\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: Wazuh agent daemon not active\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : TOOL-5190\n    # Description : Check for an IDS/IPS tool\n    Register --test-no TOOL-5190 --weight L --network NO --category security --description \"Check presence of IDS/IPS tool\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n\n        if [ ${IDS_IPS_TOOL_FOUND} -eq 1 ]; then\n            Display --indent 2 --text \"- Checking for IDS/IPS tooling\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 2 2\n        else\n            Display --indent 2 --text \"- Checking for IDS/IPS tooling\" --result \"${STATUS_NONE}\" --color YELLOW\n            #ReportSuggestion \"${TEST_NO}\" \"Install and configure automated intrusion detection/prevention tools\"\n            AddHP 0 2\n        fi\n    fi\n#\n#################################################################################\n#\n# Backup tools\n#\n#################################################################################\n#\n    # Netvault\n    # Rsync in cron\n#\n#################################################################################\n#\n    Report \"automation_tool_present=${AUTOMATION_TOOL_FOUND}\"\n\n\n    WaitForKeyPress\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_usb",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n#  USB Devices\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_USB_DEVICES}\"\n#\n#################################################################################\n#\n    USBGUARD_FOUND=0\n    USBGUARD_CONFIG=\"\"\n    USBGUARD_RULES=\"\"\n    USBGUARD_RESTORE_POLICY=\"\"\n    USBGUARD_CONTROLLER_POLICY=\"\"\n    USBGUARD_DEVICE_POLICY=\"\"\n    USBGUARD_INSERTED_POLICY=\"\"\n    USBGUARD_DEFAULT_POLICY=\"\"\n    USBGUARD_RULES_ALLOW=0\n    USBGUARD_RULES_BLOCK=0\n    USBGUARD_RULES_REJECT=0\n#\n#################################################################################\n#\n    # Test to determine if USBGuard is installed.  If it is, we will limit\n    # suggestions from other tests.\n    if [ -n \"${USBGUARDBINARY}\" ]; then\n        USBGUARD_FOUND=1\n    fi\n#\n#################################################################################\n#\n    # Test        : USB-1000 (was STRG-1840)\n    # Description : Check for disabled USB storage\n    Register --test-no USB-1000 --os Linux --weight L --network NO --category security --description \"Check if USB storage is disabled\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        LogText \"Test: Checking USB storage driver in directory /etc/modprobe.d and configuration file /etc/modprobe.conf\"\n        if [ -d /etc/modprobe.d ]; then\n            FIND=$(${LSBINARY} ${ROOTDIR}etc/modprobe.d/* 2> /dev/null)\n            if [ -n \"${FIND}\" ]; then\n                FIND=$(${GREPBINARY} -E -r \"install usb[-_]storage /bin/(false|true)\" ${ROOTDIR}etc/modprobe.d/* | ${GREPBINARY} -v \"#\")\n                FIND2=$(${GREPBINARY} -E -r \"^blacklist usb[-_]storage\" ${ROOTDIR}etc/modprobe.d/*)\n                if [ -n \"${FIND}\" -o -n \"${FIND2}\" ]; then\n                    FOUND=1\n                    LogText \"Result: found usb-storage driver in disabled state (blacklisted)\"\n                fi\n            else\n                LogText \"Result: uncommon situation. Found /etc/modprobe.d directory, but no files in it.\"\n            fi\n        fi\n        if [ -f ${ROOTDIR}etc/modprobe.conf ]; then\n            FIND=$(${GREPBINARY} -E \"install usb[-_]storage /bin/(false|true)\" ${ROOTDIR}etc/modprobe.conf | ${GREPBINARY} \"usb-storage\" | ${GREPBINARY} -v \"#\")\n            if [ -n \"${FIND}\" ]; then\n                FOUND=1\n                LogText \"Result: found usb-storage driver in disabled state\"\n            fi\n        fi\n        if [ ${FOUND} -eq 0 ]; then\n            LogText \"Result: usb-storage driver is not explicitly disabled\"\n            Display --indent 2 --text \"- Checking usb-storage driver (modprobe config)\" --result \"${STATUS_NOT_DISABLED}\" --color WHITE\n            if [ \"${USBGUARD_FOUND}\" -eq \"0\" ]; then\n                ReportSuggestion \"${TEST_NO}\" \"Disable drivers like USB storage when not used, to prevent unauthorized storage or data theft\"\n            fi\n            AddHP 2 3\n        else\n            LogText \"Result: usb-storage driver is disabled\"\n            Display --indent 2 --text \"- Checking usb-storage driver (modprobe config)\" --result \"${STATUS_DISABLED}\" --color GREEN\n            AddHP 3 3\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : USB-2000 (was STRG-1842)\n    # Description : Check USB authorizations\n    Register --test-no USB-2000 --os Linux --weight L --network NO --category security --description \"Check USB authorizations\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUND=0\n        USBDEVICESPATH=\"${ROOTDIR}sys/bus/usb/devices\"\n        LogText \"Test: checking presence of USB devices path (${USBDEVICESPATH})\"\n        if [ -d \"${USBDEVICESPATH}\" ]; then\n\n            LogText \"Test: Checking USB devices authorization to connect to the system\"\n            for device in $(find ${USBDEVICESPATH} -name \"usb*\" -type l -print); do\n                if [ -e \"${device}/authorized\" -o -e \"${device}/authorized_default\" ]; then\n                    if [ \"$(cat \"${device}/authorized_default\")\" = \"1\" ]; then\n                        FOUND=1\n                        LogText \"Test: ${device} is authorized by default (authorized_default=1)\"\n                        Report \"usb_authorized_default_device[]=${device}\"\n                    fi\n                    if [ \"$(cat \"${device}/authorized\")\" = \"1\" ]; then\n                        FOUND=1\n                        LogText \"Test: ${device} is authorized currently (authorized=1)\"\n                        Report \"usb_authorized_device[]=${device}\"\n                    fi\n                else\n                    LogText \"Test: no authorized or authorized_default file, assuming ${device} is authorized by default\"\n                    Report \"usb_authorized_default_device[]=${device}\"\n                    FOUND=1\n                fi\n            done\n\n            if [ ${FOUND} -eq 1 ]; then\n                LogText \"Result: Some USB devices are authorized by default (or temporary) to connect to the system\"\n                Display --indent 2 --text \"- Checking USB devices authorization\" --result \"${STATUS_ENABLED}\" --color YELLOW\n                # TODO: create documentation and enable the suggestion\n                #if [ ${USBGUARD_FOUND} -eq 0 ]; then\n                #   ReportSuggestion \"${TEST_NO}\" \"Disable USB devices authorization, to prevent unauthorized storage or data theft\"\n                #fi\n                AddHP 0 3\n            else\n                LogText \"Result: None USB devices are authorized by default (or temporary) to connect to the system\"\n                Display --indent 2 --text \"- Checking USB devices authorization\" --result \"${STATUS_DISABLED}\" --color GREEN\n                AddHP 3 3\n            fi\n        else\n            LogText \"Result: devices path does not exist\"\n        fi\n    fi\n\n#\n#################################################################################\n#\n    # Test        : USB-3000\n    # Description : Perform USBGuard check\n    Register --test-no USB-3000  --os Linux --weight L --network NO --category security --description \"Check for presence of USBGuard\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ ${USBGUARD_FOUND} -eq 1 ]; then\n            LogText \"Result: USBGuard is installed (${USBGUARDBINARY})\"\n            Display --indent 2 --text \"- Checking USBGuard\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 1 1\n\n            LogText \"Checking USBGuard configuration file\"\n            if [ -f ${ROOTDIR}etc/usbguard/usbguard-daemon.conf ]; then\n                USBGUARD_CONFIG=\"${ROOTDIR}etc/usbguard/usbguard-daemon.conf\"\n            else\n                USBGUARD_CONFIG=\"\"\n            fi\n\n            if [ -n \"${USBGUARD_CONFIG}\" ]; then\n                LogText \"Result: USBGuard configuration found (${USBGUARD_CONFIG})\"\n                Display --indent 4 --text \"- Configuration\" --result \"${STATUS_FOUND}\" --color GREEN\n                AddHP 1 1\n\n                LogText \"Checking USBGuard restore controller device state (RestoreControllerDeviceState)\"\n                USBGUARD_RESTORE_POLICY=$(${AWKBINARY} -F '=' -v OPT=\"RestoreControllerDeviceState\" 'index($0, OPT) == 1 {print $2}' ${USBGUARD_CONFIG})\n                if [ -n \"${USBGUARD_RESTORE_POLICY}\" ]; then\n                    LogText \"Result: RestoreControllerDeviceState = ${USBGUARD_RESTORE_POLICY}\"\n                    case \"${USBGUARD_RESTORE_POLICY}\" in\n                        \"true\")\n                            Display --indent 6 --text \"- Restore controller device state\" --result \"${USBGUARD_RESTORE_POLICY}\" --color YELLOW\n                            LogText \"  Consider changing RestoreControllerDeviceState to \\\"false\\\"\"\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Consider hardening USBGuard configuration\" \"RestoreControllerDeviceState (${USBGUARD_RESTORE_POLICY} --> false)\"\n                            AddHP 0 1\n                            ;;\n                        \"false\")\n                            Display --indent 6 --text \"- Restore controller device state\" --result \"${USBGUARD_RESTORE_POLICY}\" --color GREEN\n                            AddHP 1 1\n                            ;;\n                        *)\n                            LogText \"Result: Invalid configuration for RestoreControllerDeviceState\"\n                            Display --indent 6 --text \"- Restore controller device state\" --result \"Invalid\" --color RED\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Fix USBGuard configuration\" \"RestoreControllerDeviceState invalid \\\"${USBGUARD_RESTORE_POLICY}\\\"\"\n                            AddHP 0 1\n                            ;;\n                    esac\n\n                else\n                    LogText \"Result: RestoreControllerDeviceState not found\"\n                    Display --indent 6 --text \"- Restore controller device state\" --result \"NOT FOUND\" --color WHITE\n                    AddHP 0 1\n                fi\n\n                LogText \"Checking USBGuard rule for controllers connected before daemon starts (PresentControllerPolicy)\"\n                USBGUARD_CONTROLLER_POLICY=$(${AWKBINARY} -F '=' -v OPT=\"PresentControllerPolicy\" 'index($0, OPT) == 1 {print $2}' ${USBGUARD_CONFIG})\n                if [ -n \"${USBGUARD_CONTROLLER_POLICY}\" ]; then\n                    LogText \"Result: PresentControllerPolicy = ${USBGUARD_CONTROLLER_POLICY}\"\n                    case \"${USBGUARD_CONTROLLER_POLICY}\" in\n                        \"allow\" | \"keep\")\n                            Display --indent 6 --text \"- Rule for controllers connected before daemon starts\" --result \"${USBGUARD_CONTROLLER_POLICY}\" --color YELLOW\n                            LogText \"  Consider changing PresentControllerPolicy to \\\"apply-policy\\\", \\\"block\\\" or \\\"reject\\\"\"\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Consider hardening USBGuard configuration\" \"PresentControllerPolicy (${USBGUARD_CONTROLLER_POLICY} --> (apply-policy|block|reject)\"\n                            AddHP 0 1\n                            ;;\n                        \"apply-policy\" | \"block\" | \"reject\")\n                            Display --indent 6 --text \"- Rule for controllers connected before daemon starts\" --result \"${USBGUARD_CONTROLLER_POLICY}\" --color GREEN\n                            AddHP 1 1\n                            ;;\n                        *)\n                            LogText \"Result: Invalid configuration for PresentControllerPolicy\"\n                            Display --indent 6 --text \"- Rule for controllers connected before daemon starts\" --result \"Invalid\" --color RED\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Fix USBGuard configuration\" \"PresentControllerPolicy invalid \\\"${USBGUARD_CONTROLLER_POLICY}\\\"\"\n                            AddHP 0 1\n                            ;;\n                    esac\n                else\n                    LogText \"Result: PresentControllerPolicy not found\"\n                    Display --indent 6 --text \"- Rule for controllers connected before daemon starts\" --result \"NOT FOUND\" --color WHITE\n                    AddHP 0 1\n                fi\n\n                LogText \"Checking USBGuard rule for devices connected before daemon starts (PresentDevicePolicy)\"\n                USBGUARD_DEVICE_POLICY=$(${AWKBINARY} -F '=' -v OPT=\"PresentDevicePolicy\" 'index($0, OPT) == 1 {print $2}' ${USBGUARD_CONFIG})\n                if [ -n \"${USBGUARD_DEVICE_POLICY}\" ]; then\n                    LogText \"Result: PresentDevicePolicy = ${USBGUARD_DEVICE_POLICY}\"\n                    case \"${USBGUARD_DEVICE_POLICY}\" in\n                        \"allow\" | \"keep\")\n                            Display --indent 6 --text \"- Rule for devices connected before daemon starts\" --result \"${USBGUARD_DEVICE_POLICY}\" --color YELLOW\n                            LogText \"  Consider changing PresentDevicePolicy to \\\"apply-policy\\\", \\\"block\\\" or \\\"reject\\\"\"\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Consider hardening USBGuard configuration\" \"PresentDevicePolicy (${USBGUARD_DEVICE_POLICY} --> (apply-policy|block|reject)\"\n                            AddHP 0 1\n                            ;;\n                        \"apply-policy\" | \"block\" | \"reject\")\n                            Display --indent 6 --text \"- Rule for devices connected before daemon starts\" --result \"${USBGUARD_DEVICE_POLICY}\" --color GREEN\n                            AddHP 1 1\n                            ;;\n                        *)\n                            LogText \"Result: Invalid configuration for PresentDevicePolicy\"\n                            Display --indent 6 --text \"- Rule for devices connected before daemon starts\" --result \"Invalid\" --color RED\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Fix USBGuard configuration\" \"PresentDevicePolicy invalid \\\"${USBGUARD_DEVICE_POLICY}\\\"\"\n                            AddHP 0 1\n                            ;;\n                    esac\n                else\n                    LogText \"Result: PresentDevicePolicy not found\"\n                    Display --indent 6 --text \"- Rule for devices connected before daemon starts\" --result \"NOT FOUND\" --color WHITE\n                    AddHP 0 1\n                fi\n\n                LogText \"Checking USBGuard rule for devices inserted after daemon starts (InsertedDevicePolicy)\"\n                USBGUARD_INSERTED_POLICY=$(${AWKBINARY} -F '=' -v OPT=\"InsertedDevicePolicy\" 'index($0, OPT) == 1 {print $2}' ${USBGUARD_CONFIG})\n                if [ -n \"${USBGUARD_INSERTED_POLICY}\" ]; then\n                    LogText \"Result: InsertedDevicePolicy = ${USBGUARD_INSERTED_POLICY}\"\n                    case \"${USBGUARD_INSERTED_POLICY}\" in\n                        \"allow\" | \"keep\")\n                            Display --indent 6 --text \"- Rule for devices inserted after daemon starts\" --result \"${USBGUARD_INSERTED_POLICY}\" --color YELLOW\n                            LogText \"  Consider changing InsertedDevicePolicy to \\\"apply-policy\\\", \\\"block\\\" or \\\"reject\\\"\"\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Consider hardening USBGuard configuration\" \"InsertedDevicePolicy (${USBGUARD_INSERTED_POLICY} --> (apply-policy|block|reject)\"\n                            AddHP 0 1\n                            ;;\n                        \"apply-policy\" | \"block\" | \"reject\")\n                            Display --indent 6 --text \"- Rule for devices inserted after daemon starts\" --result \"${USBGUARD_INSERTED_POLICY}\" --color GREEN\n                            AddHP 1 1\n                            ;;\n                        *)\n                            LogText \"Result: Invalid configuration for InsertedDevicePolicy\"\n                            Display --indent 6 --text \"- Rule for devices inserted after daemon starts\" --result \"Invalid\" --color RED\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Fix USBGuard configuration\" \"InsertedDevicePolicy invalid \\\"${USBGUARD_INSERTED_POLICY}\\\"\"\n                            AddHP 0 1\n                            ;;\n                    esac\n                else\n                    LogText \"Result: InsertedDevicePolicy not found\"\n                    Display --indent 6 --text \"- Rule for devices inserted after daemon starts\" --result \"NOT FOUND\" --color WHITE\n                    AddHP 0 1\n                fi\n\n                LogText \"Checking USBGuard rule for devices not in RuleFile (ImplicitPolicyTarget)\"\n                USBGUARD_DEFAULT_POLICY=$(${AWKBINARY} -F '=' -v OPT=\"ImplicitPolicyTarget\" 'index($0, OPT) == 1 {print $2}' ${USBGUARD_CONFIG})\n                if [ -n \"${USBGUARD_DEFAULT_POLICY}\" ]; then\n                    LogText \"Result: ImplicitPolicyTarget = ${USBGUARD_DEFAULT_POLICY}\"\n                    case \"${USBGUARD_DEFAULT_POLICY}\" in\n                        \"allow\")\n                            Display --indent 6 --text \"- Rule for devices not in RuleFile\" --result \"${USBGUARD_DEFAULT_POLICY}\" --color YELLOW\n                            LogText \"  Consider changing ImplicitPolicyTarget to \\\"block\\\" or \\\"reject\\\"\"\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Consider hardening USBGuard configuration\" \"ImplicitPolicyTarget (${USBGUARD_DEFAULT_POLICY} --> (block|reject)\"\n                            AddHP 0 1\n                            ;;\n                        \"block\"|\"reject\")\n                            Display --indent 6 --text \"- Rule for devices not in RuleFile\" --result \"${USBGUARD_DEFAULT_POLICY}\" --color GREEN\n                            AddHP 1 1\n                            ;;\n                        *)\n                            LogText \"Result: Invalid configuration for ImplicitPolicyTarget\"\n                            Display --indent 6 --text \"- Rule for devices not in RuleFile\" --result \"Invalid\" --color RED\n                            # TODO: assign TEST_NO, create documentation, and enable the suggestion\n                            # ReportSuggestion \"${TEST_NO}\" \"Fix USBGuard configuration\" \"ImplicitPolicyTarget invalid \\\"${USBGUARD_DEFAULT_POLICY}\\\"\"\n                            AddHP 0 1\n                            ;;\n                    esac\n                else\n                    LogText \"Result: ImplicitPolicyTarget not found\"\n                    Display --indent 4 --text \"- Rule for devices not in RuleFile\" --result \"NOT FOUND\" --color WHITE\n                    AddHP 0 1\n                fi\n\n                LogText \"Checking RuleFile\"\n                USBGUARD_RULES=$(${AWKBINARY} -F '=' -v OPT=\"RuleFile\" 'index($0, OPT) == 1 {print $2}' ${USBGUARD_CONFIG})\n                if [ -n \"${USBGUARD_RULES}\" ] && [ -f \"${USBGUARD_RULES}\" ]; then\n                    LogText \"Result: RuleFile found (${USBGUARD_RULES})\"\n                    Display --indent 4 --text \"- RuleFile\" --result \"${STATUS_FOUND}\" --color GREEN\n                    AddHP 1 1\n\n                    USBGUARD_RULES_ALLOW=$(${GREPBINARY} -E -c \"^allow\" ${USBGUARD_RULES})\n                    Display --indent 6 --text \"- Controllers & Devices allow\" --result \"${USBGUARD_RULES_ALLOW}\" --color WHITE\n                    USBGUARD_RULES_BLOCK=$(${GREPBINARY} -E -c \"^block\" ${USBGUARD_RULES})\n                    Display --indent 6 --text \"- Controllers & Devices block\" --result \"${USBGUARD_RULES_BLOCK}\" --color WHITE\n                    USBGUARD_RULES_REJECT=$(${GREPBINARY} -E -c \"^reject\" ${USBGUARD_RULES})\n                    Display --indent 6 --text \"- Controllers & Devices reject\" --result \"${USBGUARD_RULES_REJECT}\" --color WHITE\n                else\n                    LogText \"Result: RuleFile not found (\\\"man usbguard\\\" for instructions to install initial policies)\"\n                    Display --indent 4 --text \"- RuleFile\" --result \"${STATUS_NOT_FOUND}\" --color RED\n                    # To-Be-Added: assign TEST_NO, create documentation, and enable the suggestion\n                    #ReportSuggestion \"${TEST_NO}\" \"Install USBGuard RuleFile\" \"\\\"man usbguard\\\" for instructions to install initial policies\"\n                    AddHP 0 1\n                fi\n\n            else\n                Display --indent 4 --text \"- Configuration\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n                LogText \"Result: Configuration not found\"\n                # To-Be-Added: assign TEST_NO, create documentation, and enable the suggestion\n                #ReportSuggestion \"${TEST_NO}\" \"USBGuard configuration file not found, consider reinstalling\"\n                AddHP 0 7\n            fi\n        else\n            LogText \"Result: USBGuard not found\"\n            Display --indent 2 --text \"- Checking USBGuard\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            # To-Be-Added: assign TEST_NO, create documentation, and enable the suggestion\n            #ReportSuggestion \"${TEST_NO}\" \"Install USBGuard to allow for fine-grained control of USB authorization\"\n            AddHP 0 8\n        fi\n\n    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_virtualization",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Virtualization\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_VIRTUALIZATION}\"\n#\n#################################################################################\n#\n#    # Test        : VIRT-1920\n#    # Description : Checking VMware\n#    Register --test-no VIRT-1920 --weight L --network NO --category security --description \"Checking VMware guest status\"\n#    if [ ${SKIPTEST} -eq 0 ]; then\n#        VMWARE_GUEST=0\n#        Display --indent 2 --text \"- Checking VMware guest status\"\n#        # check memory driver file\n#        # check LKM list\n#        # check vmware tools\n#        LogText \"Test: checking VMware tools daemon presence\"\n#        if [ ! \"${VMWARETOOLSBINARY}\" = \"\" ]; then\n#            LogText \"Result: VMware tools binary found\"\n#            VMWARE_GUEST=1\n#            Display --indent 4 --text \"- Checking VMware tools daemon\" --result \"${STATUS_FOUND}\" --color GREEN\n#          else\n#            Display --indent 4 --text \"- Checking VMware tools daemon\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n#        fi\n#\n#    fi\n#\n#################################################################################\n#\n\nWaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tests_webservers",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : https://linux-audit.com/\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Software: webserver\n#\n#################################################################################\n#\n    InsertSection \"${SECTION_WEBSERVER}\"\n#\n#################################################################################\n#\n    # Reset Apache status\n    APACHE_INSTALLED=0\n    APACHE_MODULES_ENABLED_LOCS=\"${ROOTDIR}etc/apache2/mods-enabled\"\n    APACHE_MODULES_LOCS=\"${ROOTDIR}etc/httpd/modules ${ROOTDIR}opt/local/apache2/modules ${ROOTDIR}usr/lib/apache ${ROOTDIR}usr/lib/apache2 ${ROOTDIR}usr/lib/httpd/modules ${ROOTDIR}usr/libexec/apache2 ${ROOTDIR}usr/lib64/apache2 ${ROOTDIR}usr/lib64/apache2/modules ${ROOTDIR}usr/lib64/httpd/modules ${ROOTDIR}usr/local/libexec/apache ${ROOTDIR}usr/local/libexec/apache22 ${ROOTDIR}usr/local/libexec/apache24\"\n    NGINX_RUNNING=0\n    NGINX_CONF_LOCS=\"${ROOTDIR}etc/nginx ${ROOTDIR}usr/local/etc/nginx ${ROOTDIR}usr/local/nginx/conf\"\n    NGINX_CONF_LOCATION=\"\"\n    NGINX_CONF_FILES=\"\"\n    NGINX_CONF_FILES_ADDITIONS=\"\"\n#\n#################################################################################\n#\n    sTEST_APACHE_TARGETS=\"${ROOTDIR}etc/apache ${ROOTDIR}etc/apache2 ${ROOTDIR}etc/httpd \\\n        ${ROOTDIR}opt/apache \\\n        ${ROOTDIR}usr/local/apache ${ROOTDIR}usr/local/apache2 \\\n        ${ROOTDIR}usr/local/etc/apache ${ROOTDIR}usr/local/etc/apache2 ${ROOTDIR}usr/local/etc/apache22 \\\n        ${ROOTDIR}usr/pkg/etc/httpd ${ROOTDIR}etc/sysconfig/apache2 ${ROOTDIR}usr/local/etc/apache24\"\n\n    CreateTempFile || ExitFatal\n    TMPFILE=\"${TEMP_FILE}\"\n    CreateTempFile || ExitFatal\n    TMPFILE2=\"${TEMP_FILE}\"\n    CreateTempFile || ExitFatal\n    TMPFILE3=\"${TEMP_FILE}\"\n#\n#################################################################################\n#\n    # Test        : HTTP-6622\n    # Description : Test for Apache installation\n    # Notes       : Do not run on NetBSD, -v is unknown option for httpd binary\n    #               On OpenBSD do not run /usr/sbin/httpd with -v: builtin non-Apache\n    if [ ! \"${OS}\" = \"NetBSD\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6622 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking Apache presence\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        if [ \"${OS}\" = \"OpenBSD\" -a \"${HTTPDBINARY}\" = \"/usr/sbin/httpd\" ]; then HTTPDBINARY=\"\"; fi\n        if IsEmpty \"${HTTPDBINARY}\"; then\n            Display --indent 2 --text \"- Checking Apache\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        else\n            LogText \"Test: Scanning for Apache binary\"\n            IS_APACHE=$(${HTTPDBINARY} -v 2> /dev/null | ${GREPBINARY} -E '[aA]pache')\n            if IsEmpty \"${IS_APACHE}\"; then\n                LogText \"Result: ${HTTPDBINARY} is not Apache\"\n                Display --indent 2 --text \"- Checking Apache (binary ${HTTPDBINARY})\" --result \"NO MATCH\" --color WHITE\n            else\n                Display --indent 2 --text \"- Checking Apache (binary ${HTTPDBINARY})\" --result \"${STATUS_FOUND}\" --color GREEN\n                LogText \"Result: ${HTTPDBINARY} seems to be Apache HTTP daemon\"\n                APACHE_INSTALLED=1\n                APACHE_VERSION=$(${HTTPDBINARY} -v 2> /dev/null | ${GREPBINARY} \"^Server version:\" | ${AWKBINARY} '{ print $3 }' | ${AWKBINARY} -F/ '{ print $2 }')\n                LogText \"Apache version: ${APACHE_VERSION}\"\n                Report \"apache_version=${APACHE_VERSION}\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6624\n    # Description : Testing main Apache configuration file\n    # Notes       : Do not run on OpenBSD/NetBSD, as -V is an unknown option for httpd binary\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then\n        if [ ! \"${OS}\" = \"NetBSD\" -a ! \"${OS}\" = \"OpenBSD\" ]; then\n            PREQS_MET=\"YES\"\n        else\n            PREQS_MET=\"NO\"\n        fi\n    else\n        PREQS_MET=\"NO\"\n    fi\n    Register --test-no HTTP-6624 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Testing main Apache configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        APACHE_CONFIGFILE=\"\"\n        APACHE_TEST=$(${HTTPDBINARY} -V 2> /dev/null | ${GREPBINARY} \"\\-D SERVER_CONFIG_FILE=\" | ${SEDBINARY} 's/[ ]-D SERVER_CONFIG_FILE=//' | ${TRBINARY} -d '\"' | ${TRBINARY} -d ' ' | ${TRBINARY} -d '[:cntrl:]')\n\n        if IsEmpty \"${APACHE_TEST}\"; then\n            LogText \"Result: Can't find the configuration file, so skipping some Apache related tests\"\n        else\n            # We found a possible match. Checking if it's valid filename. If not, we need to add a prefix\n            if [ -f ${APACHE_TEST} ]; then\n                APACHE_CONFIGFILE=\"${APACHE_TEST}\"\n                Display --indent 6 --text \"Info: Configuration file found (${APACHE_CONFIGFILE})\"\n            else\n                # Probably the prefix is missing, so we are going to search that\n                APACHE_HTTPDROOT=$(${HTTPDBINARY} -V 2> /dev/null | ${GREPBINARY} \"\\-D HTTPD_ROOT=\" | ${SEDBINARY} 's/[ ]-D HTTPD_ROOT=//' | ${TRBINARY} -d '\"' | ${TRBINARY} -d ' ')\n                APACHE_TESTFILE=\"${APACHE_HTTPDROOT}/${APACHE_TEST}\"\n                if [ -f ${APACHE_TESTFILE} ]; then\n                    APACHE_CONFIGFILE=\"${APACHE_TESTFILE}\"\n                    Display --indent 6 --text \"Info: Configuration file found (${APACHE_CONFIGFILE})\"\n                    LogText \"Result: Configuration file found (${APACHE_CONFIGFILE})\"\n                else\n                    LogText \"Result: File or directory ${APACHE_TESTFILE} does not exist\"\n                    Display --indent 6 --text \"[Notice] possible directory/file parts found, but still unsure what the real configuration file is. Skipping some Apache related tests\"\n                    ReportException \"${TEST_NO}:1\" \"Found some unknown directory or file references in Apache configuration\"\n                    LogText \"Note: if only the Apache binary package has been installed, then the configuration might be missing. Is the Apache package really needed?\"\n                fi\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6626\n    # Description : Testing other Apache configuration files\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6626 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Testing other Apache configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for DIR in ${sTEST_APACHE_TARGETS}; do\n            if [ -d ${DIR} ]; then\n                find ${DIR} -name \"*.conf\" -print >> ${TMPFILE2}\n            fi\n        done\n\n        # Sort unsorted list, save it in temp file and then remove unsorted list\n        if [ -f ${TMPFILE2} ]; then\n            ${SORTBINARY} -u ${TMPFILE2} >> ${TMPFILE}\n            rm -f ${TMPFILE2}\n        fi\n        cVHOSTS=0; tVHOSTS=\"\"\n\n        # Check every configuration file\n        for I in $(cat ${TMPFILE}); do\n            LogText \"Apache config file: ${I}\"\n\n            FileIsReadable ${I}\n            if [ ${CANREAD} -eq 1 ]; then\n                # Search Virtual Hosts\n                for J in $(${GREPBINARY} \"ServerName\" ${I} | ${GREPBINARY} -v \"^#\" | ${AWKBINARY} '{ if ($1==\"ServerName\" && $2!=\"*\" && $2!=\"default\") print $2 }'); do\n                    if HasData \"${J}\"; then\n                        tVHOSTS=\"${tVHOSTS} ${J}\"\n                        cVHOSTS=$((cVHOSTS + 1))\n                    fi\n                done\n                # Search Server aliases\n                for J in $(${GREPBINARY} \"ServerAlias\" ${I} | ${GREPBINARY} -v \"^#\" | ${SEDBINARY} \"s/\\s*ServerAlias //g\" | ${SEDBINARY} \"s/#.*//g\"); do\n                    if [ -n \"${J}\" ]; then\n                        tVHOSTS=\"${tVHOSTS} ${J}\"\n                        cVHOSTS=$((cVHOSTS + 1))\n                    fi\n                done\n            else\n                LogText \"Result: can not read configuration file with this user ID\"\n                ReportException \"${TEST_NO}:1\" \"Can not read configuration file $I\"\n            fi\n        done\n\n        # Log all virtual hosts we found\n            for J in ${tVHOSTS}; do\n                if [ -n \"${J}\" ]; then\n                    LogText \"Virtual host: ${J}\"\n                    #Report \"apache_vhost_name[]=${J}\"\n                fi\n            done\n\n        # Show number of vhosts if we found any\n        LogText \"Result: found ${cVHOSTS} virtual hosts\"\n        if [ ${cVHOSTS} -gt 0 ]; then\n            Display --indent 6 --text \"Info: Found ${cVHOSTS} virtual hosts\"\n        else\n            Display --indent 6 --text \"Info: No virtual hosts found\"\n        fi\n    fi\n\n    # Remove temp files\n    if [ -f ${TMPFILE} -a -n \"${TMPFILE}\" ]; then\n        rm -f ${TMPFILE}\n    fi\n    if [ -n \"${TMPFILE2}\" ]; then if [ -f ${TMPFILE2} ]; then rm -f ${TMPFILE2}; fi; fi\n#\n#################################################################################\n#\n    # TODO\n    # Do you have Apache running and want to contribute? Help us testing this control and send in a pull request\n\n    # Test        : HTTP-6630\n    # Description : Search for all loaded modules\n    #if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    #Register --test-no HTTP-6630 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Determining all loaded Apache modules\"\n    #if [ ${SKIPTEST} -eq 0 ]; then\n    #    # Testing Debian style\n    #    LogText \"Test: searching loaded/enabled Apache modules\"\n    #    apachectl -t -D DUMP_MODULES 2>&1 | ${GREPBINARY} -E -v \"(Loaded Modules|Syntax OK)\" | ${SEDBINARY} 's/(\\(shared\\|static\\))//' | ${SEDBINARY} 's/ //'\n    #    for I in ${APACHE_MODULES_ENABLED_LOCS}; do\n    #        LogText \"Test: checking ${I}\"\n    #        if [ -d ${I} ]; then\n    #            FIND=$(${GREPBINARY} -r LoadModule ${I}/* | ${GREPBINARY} -v \"^#\" | ${AWKBINARY} '{ print $2\":\"$3 }')\n    #          else\n    #            LogText \"Result: ${I} does not exist\"\n    #        fi\n    #    done\n    #fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6632\n    # Description : Search for available Apache modules\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6632 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Determining all available Apache modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching available Apache modules\"\n        COUNT=0\n        for DIR in ${APACHE_MODULES_LOCS}; do\n            DirectoryExists ${DIR}\n            if [ ${DIRECTORY_FOUND} -eq 1 ]; then\n                FIND=$(${FINDBINARY} ${DIR} -name \"mod_*\" -print | ${SORTBINARY})\n                for ITEM in ${FIND}; do\n                    Report \"apache_module[]=${ITEM}\"\n                    LogText \"Result: found Apache module ${ITEM}\"\n                    COUNT=$((COUNT + 1))\n                done\n            fi\n        done\n        if [ ${COUNT} -eq 0 ]; then\n            Display --indent 4 --text \"* Loadable modules\" --result \"${STATUS_NONE}\" --color WHITE\n            ReportException \"${TEST_NO}:1\" \"No loadable Apache modules found\"\n        else\n            Display --indent 4 --text \"* Loadable modules\" --result \"${STATUS_FOUND} (${COUNT})\" --color GREEN\n            Display --indent 8 --text \"- Found ${COUNT} loadable modules\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6640\n    # Description : Search for special Apache modules: evasive\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6640 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Determining existence of specific Apache modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check modules, module\n        if CheckItem \"apache_module\" \"/mod_evasive([0-9][0-9])?.so\"; then\n            Display --indent 10 --text \"mod_evasive: anti-DoS/brute force\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            Display --indent 10 --text \"mod_evasive: anti-DoS/brute force\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            AddHP 2 3\n            ReportSuggestion \"${TEST_NO}\" \"Install Apache mod_evasive to guard webserver against DoS/brute force attempts\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6641\n    # Description : Search for special Apache modules: Quality of Service\n    # Notes       : Was mod_qos before. Since Apache 2.2.15 mod_reqtimeout\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6641 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Determining existence of specific Apache modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check modules, module\n        if CheckItem \"apache_module\" \"/mod_(reqtimeout|qos).so\"; then\n            Display --indent 10 --text \"mod_reqtimeout/mod_qos\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            Display --indent 10 --text \"mod_reqtimeout/mod_qos\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            AddHP 2 3\n            ReportSuggestion \"${TEST_NO}\" \"Install Apache mod_reqtimeout or mod_qos to guard webserver against Slowloris attacks\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6643\n    # Description : Search for special Apache modules: security\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6643 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Determining existence of specific Apache modules\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # Check modules, module\n        if CheckItem \"apache_module\" \"/mod_security(2|3).so\" ; then\n            Display --indent 10 --text \"ModSecurity: web application firewall\" --result \"${STATUS_FOUND}\" --color GREEN\n            AddHP 3 3\n        else\n            Display --indent 10 --text \"ModSecurity: web application firewall\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n            AddHP 2 3\n            ReportSuggestion \"${TEST_NO}\" \"Install Apache modsecurity to guard webserver against web application attacks\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6660\n    # Description : Search for \"TraceEnable off\" in configuration files\n    if [ ${APACHE_INSTALLED} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6660 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Checking Apache security setting: TraceEnable\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for DIR in ${sTEST_APACHE_TARGETS}; do\n            if [ -d ${DIR} ]; then\n                find ${DIR} -name \"*.conf\" -print >> ${TMPFILE3}\n            fi\n        done\n\n        # Check all Apache conf-files for TraceEnable\n        if [ -f ${TMPFILE3} ]; then\n            Display --indent 2 --text '- Checking TraceEnable setting in:'\n            for APACHE_CONFFILE in $(cat ${TMPFILE3}); do\n                TRACEENABLE=$( ${GREPBINARY} -i -E '^TraceEnable' ${APACHE_CONFFILE} | ${AWKBINARY} '{print $2}' )\n                if [ ! ${TRACEENABLE} ]; then\n                    LogText \"Result: no TraceEnable setting found in ${APACHE_CONFFILE}\"\n                    Display --indent 4 --text \"  ${APACHE_CONFFILE}\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n                else\n                    TRACEENABLED_SETTING=$( echo ${TRACEENABLE} | tr 'A-Z' 'a-z' )\n                    if [ \"x${TRACEENABLED_SETTING}\" = 'xoff' ]; then\n                        LogText \"Result: found TraceEnable setting set to 'off' in ${APACHE_CONFFILE}\"\n                        Report \"Apache setting: 'TraceEnable Off' in ${APACHE_CONFFILE}\"\n                        Display --indent 4 --text \"  ${APACHE_CONFFILE}\" --result \"${STATUS_FOUND}\" --color GREEN\n                    else\n                        LogText \"Result: found TraceEnable setting set to '\"${TRACEENABLE}\"' in ${APACHE_CONFFILE}\"\n                        Report \"Apache setting: 'TraceEnable \"${TRACEENABLE}\"' in ${APACHE_CONFFILE}\"\n                        Display --indent 4 --text \"  ${APACHE_CONFFILE}\" --result \"${STATUS_SUGGESTION}\" --color YELLOW\n                        ReportSuggestion \"${TEST_NO}\" \"Consider setting 'TraceEnable Off' in ${APACHE_CONFFILE}\" \"Set TraceEnable to 'On' or 'extended' for testing and diagnostic purposes only.\"\n                    fi\n                fi\n            done\n            rm -f ${TMPFILE3}\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6702\n    # Description : Search for nginx process\n    Register --test-no HTTP-6702 --weight L --network NO --category security --description \"Check nginx process\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching running nginx process\"\n        if IsRunning \"nginx\"; then\n            LogText \"Result: found running nginx process(es)\"\n            Display --indent 2 --text \"- Checking nginx\" --result \"${STATUS_FOUND}\" --color GREEN\n            NGINX_RUNNING=1\n            Report \"nginx_running=1\"\n        else\n            LogText \"Result: no running nginx process found\"\n            Display --indent 2 --text \"- Checking nginx\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6704\n    # Description : Search for nginx configuration file\n    if [ ${NGINX_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6704 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nginx configuration file\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: searching nginx configuration file\"\n        for DIR in ${NGINX_CONF_LOCS}; do\n            if [ -f ${DIR}/nginx.conf ]; then\n                NGINX_CONF_LOCATION=\"${DIR}/nginx.conf\"\n                LogText \"Found file ${NGINX_CONF_LOCATION}\"\n                NGINX_CONF_FILES=\"${DIR}/nginx.conf\"\n            fi\n        done\n        if HasData \"${NGINX_CONF_LOCATION}\"; then\n            LogText \"Result: found nginx configuration file\"\n            Report \"nginx_main_conf_file=${NGINX_CONF_LOCATION}\"\n            Display --indent 4 --text \"- Searching nginx configuration file\" --result \"${STATUS_FOUND}\" --color GREEN\n        else\n            LogText \"Result: no nginx configuration file found\"\n            Display --indent 2 --text \"- Searching nginx configuration file\" --result \"${STATUS_NOT_FOUND}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6706\n    # Description : Search for includes within nginx configuration file\n    # Notes       : Daemon nginx should be running, nginx.conf should be found\n    if [ ${NGINX_RUNNING} -eq 1 -a -n \"${NGINX_CONF_LOCATION}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6706 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for additional nginx configuration files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        CreateTempFile || ExitFatal\n        TMPFILE=\"${TEMP_FILE}\"\n\n        COUNT=0\n        ${SEDBINARY} -e 's/^[ \\t]*//' ${NGINX_CONF_LOCATION} | ${GREPBINARY} -v \"^#\" | ${GREPBINARY} -v \"^$\" | ${SEDBINARY} 's/[\\t]/ /g' | ${SEDBINARY} 's/  / /g' | ${SEDBINARY} 's/  / /g' >> ${TMPFILE}\n        # Search for included configuration files (may include directories and wild cards)\n        FIND=$(${GREPBINARY} \"include\" ${NGINX_CONF_LOCATION} | ${AWKBINARY} '{ if ($1==\"include\") { print $2 }}' | ${SEDBINARY} 's/;$//g')\n        for I in ${FIND}; do\n            FIND2=$(${LSBINARY} ${I} 2>/dev/null)\n            for J in ${FIND2}; do\n                # Ensure that we are parsing normal files\n                if [ -f ${J} ]; then\n                    COUNT=$((COUNT + 1))\n                    LogText \"Result: found Nginx configuration file ${J}\"\n                    Report \"nginx_sub_conf_file[]=${J}\"\n                    FileIsReadable ${J}\n                    if [ ${CANREAD} -eq 1 ]; then\n                        NGINX_CONF_FILES=\"${NGINX_CONF_FILES} ${J}\"\n                        FIND3=$(sed -e 's/^[ \\t]*//' ${J} | ${GREPBINARY} -v \"^#\" | ${GREPBINARY} -v \"^$\" | ${SEDBINARY} 's/[\\t]/ /g' | ${SEDBINARY} 's/  / /g' | ${SEDBINARY} 's/  / /g' >> ${TMPFILE})\n                    else\n                        ReportException \"${TEST_NO}:1\" \"Can not parse file ${J}, as it is not readable\"\n                    fi\n                fi\n            done\n        done\n\n        # Sort all discovered configuration lines and store unique ones. Also strip out the mime types configured in nginx\n        SORTFILE=$(${SORTBINARY} -u ${TMPFILE} | ${SEDBINARY} 's/ /:space:/g' | ${GREPBINARY} -E -v \"(application|audio|image|text|video)/\" | ${GREPBINARY} -E -v \"({|})\")\n        for I in ${SORTFILE}; do\n            I=$(echo ${I} | ${SEDBINARY} 's/:space:/ /g')\n            Report \"nginx_config_option[]=${I}\";\n        done\n\n        # Remove unsorted file for next tests\n        if [ -f ${TMPFILE} ]; then rm -f ${TMPFILE}; fi\n\n        if [ ${COUNT} -eq 0 ]; then\n            LogText \"Result: no nginx include statements found\"\n        else\n            Display --indent 6 --text \"- Found nginx includes\" --result \"${COUNT} FOUND\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6708\n    # Description : Check discovered nginx configuration settings for further hardening\n    # Notes       : Daemon of nginx should be running, nginx.conf should be found\n    if [ ${NGINX_RUNNING} -eq 1 -a -n \"${NGINX_CONF_FILES}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6708 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check discovered nginx configuration settings\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: start parsing all discovered nginx options\"\n        Display --indent 4 --text \"- Parsing configuration options\"\n        for FILE in ${NGINX_CONF_FILES}; do\n            FILENAME=$(echo ${FILE} | ${AWKBINARY} -F/ '{print $NF}')\n            if [ ! \"${FILENAME}\" = \"mime.types\" ]; then\n                if FileIsReadable ${FILE}; then\n                    Display --indent 8 --text \"- ${FILE}\"\n                    ParseNginx ${FILE}\n                else\n                    Display --indent 8 --text \"- ${FILE}\" --result \"SKIPPED (NOT READABLE)\" --color YELLOW\n                fi\n            else\n                LogText \"Result: this configuration file is skipped, as it contains usually no interesting details\"\n            fi\n        done\n        if [ -n \"${NGINX_CONF_FILES_ADDITIONS}\" ]; then\n            for I in ${NGINX_CONF_FILES_ADDITIONS}; do\n                FILENAME=$(echo ${I} | ${AWKBINARY} -F/ '{print $NF}')\n                if [ ! \"${FILENAME}\" = \"mime.types\" ]; then\n                    if FileIsReadable ${I}; then\n                        Display --indent 8 --text \"- ${I}\"\n                        ParseNginx ${I}\n                    else\n                        Display --indent 8 --text \"- ${I}\" --result \"SKIPPED (NOT READABLE)\" --color YELLOW\n                    fi\n                else\n                    LogText \"Result: this configuration file is skipped, as it contains usually no interesting details\"\n                fi\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6710\n    # Description : Check SSL configuration of nginx\n    # Notes       : Daemon of nginx should be running, nginx.conf should be found\n    if [ ${NGINX_RUNNING} -eq 1 -a -n \"${NGINX_CONF_LOCATION}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6710 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nginx SSL configuration settings\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        NGINX_SSL_SUGGESTION=0\n        if [ ${NGINX_SSL_ON} -eq 1 ]; then\n            LogText \"Result: SSL is configured in nginx on one or more virtual hosts\"\n            Display --indent 6 --text \"- SSL configured\" --result \"${STATUS_YES}\" --color GREEN\n            AddHP 5 5\n            # Cipher tests\n            if [ ${NGINX_SSL_CIPHERS} -eq 1 ]; then\n                Display --indent 8 --text \"- Ciphers configured\" --result \"${STATUS_YES}\" --color GREEN\n            else\n                Display --indent 8 --text \"- Ciphers configured\" --result \"${STATUS_NO}\" --color RED\n                NGINX_SSL_SUGGESTION=1\n            fi\n\n            if [ ${NGINX_SSL_PREFER_SERVER_CIPHERS} -eq 1 ]; then\n                Display --indent 8 --text \"- Prefer server ciphers\" --result \"${STATUS_YES}\" --color GREEN\n            else\n                Display --indent 8 --text \"- Prefer server ciphers\" --result \"${STATUS_NO}\" --color RED\n                NGINX_SSL_SUGGESTION=1\n            fi\n\n            if [ ${NGINX_SSL_PROTOCOLS} -eq 1 ]; then\n                Display --indent 8 --text \"- Protocols configured\" --result \"${STATUS_YES}\" --color GREEN\n                if [ ${NGINX_WEAK_SSL_PROTOCOL_FOUND} -eq 0 ]; then\n                    Display --indent 10 --text \"- Insecure protocols found\" --result \"${STATUS_NO}\" --color GREEN\n                else\n                    Display --indent 10 --text \"- Insecure protocols found\" --result \"${STATUS_YES}\" --color RED\n                    ReportSuggestion \"${TEST_NO}\" \"Disable weak protocol in nginx configuration\"\n                fi\n            else\n                Display --indent 8 --text \"- Protocols configured\" --result \"${STATUS_NO}\" --color RED\n                NGINX_SSL_SUGGESTION=1\n            fi\n        else\n            LogText \"Result: No SSL configuration found\"\n            Display --indent 6 --text \"- SSL configured\" --result \"${STATUS_NO}\" --color RED\n            ReportSuggestion \"${TEST_NO}\" \"Add HTTPS to nginx virtual hosts for enhanced protection of sensitive data and privacy\"\n            AddHP 1 5\n        fi\n        if [ ${NGINX_SSL_SUGGESTION} -eq 1 ]; then\n            LogText \"Result: one or more parts of the nginx configuration could be enhanced regarding SSL\"\n            ReportSuggestion \"${TEST_NO}\" \"Change the HTTPS and SSL settings for enhanced protection of sensitive data and privacy\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6712\n    # Description : Check logging configuration of nginx\n    # Notes       : Daemon of nginx should be running, nginx.conf should be found\n    if [ ${NGINX_RUNNING} -eq 1 -a -n \"${NGINX_CONF_LOCATION}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6712 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check nginx access logging\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        NGINX_LOG_SUGGESTION=0\n        Display --indent 6 --text \"- Checking log file configuration\"\n\n        # Check for missing access log\n        if [ ${NGINX_ACCESS_LOG_MISSING} -eq 1 ]; then\n            NGINX_LOG_SUGGESTION=1\n            Display --indent 8 --text \"- Missing log files (access_log)\" --result \"${STATUS_YES}\" --color RED\n        else\n            Display --indent 8 --text \"- Missing log files (access_log)\" --result \"${STATUS_NO}\" --color GREEN\n        fi\n        # Access log disabled\n        if [ ${NGINX_ACCESS_LOG_DISABLED} -eq 1 ]; then\n            NGINX_LOG_SUGGESTION=1\n            LogText \"Result: found one or more virtual hosts which have their access log disabled\"\n            Display --indent 8 --text \"- Disabled access logging\" --result \"${STATUS_YES}\" --color RED\n            AddHP 2 3\n        else\n            LogText \"Result: no virtual hosts found which have their access log disabled\"\n            Display --indent 8 --text \"- Disabled access logging\" --result \"${STATUS_NO}\" --color GREEN\n            AddHP 3 3\n        fi\n        # Report suggestion\n        if [ ${NGINX_LOG_SUGGESTION} -eq 1 ]; then\n            ReportSuggestion \"${TEST_NO}\" \"Check your nginx access log for proper functioning\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6714\n    # Description : Check missing error logs in nginx\n    if [ ${NGINX_RUNNING} -eq 1 -a -n \"${NGINX_CONF_LOCATION}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6714 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for missing error logs in nginx\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        NGINX_LOG_SUGGESTION=0\n        # Check for missing access log\n        if [ ${NGINX_ERROR_LOG_MISSING} -eq 1 ]; then\n            NGINX_LOG_SUGGESTION=1\n            Display --indent 8 --text \"- Missing log files (error_log)\" --result \"${STATUS_YES}\" --color RED\n        else\n            Display --indent 8 --text \"- Missing log files (error_log)\" --result \"${STATUS_NO}\" --color GREEN\n        fi\n        # Report suggestion\n        if [ ${NGINX_LOG_SUGGESTION} -eq 1 ]; then\n            ReportSuggestion \"${TEST_NO}\" \"Check your nginx error_log statements\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6716\n    # Description : Check debug mode on error log in nginx\n    if [ ${NGINX_RUNNING} -eq 1 -a -n \"${NGINX_CONF_LOCATION}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6716 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check for debug mode on error log in nginx\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        NGINX_LOG_SUGGESTION=0\n        # Access log in debug mode\n        if [ ${NGINX_ERROR_LOG_DEBUG} -eq 1 ]; then\n            NGINX_LOG_SUGGESTION=1\n            LogText \"Result: found one or more virtual hosts which have their error log in debug mode\"\n            Display --indent 8 --text \"- Debugging mode on error_log\" --result \"${STATUS_YES}\" --color RED\n            AddHP 2 3\n        else\n            LogText \"Result: no virtual hosts found which have their error log in debug mode\"\n            Display --indent 8 --text \"- Debugging mode on error_log\" --result \"${STATUS_NO}\" --color GREEN\n            AddHP 3 3\n        fi\n        # Report suggestion\n        if [ ${NGINX_LOG_SUGGESTION} -eq 1 ]; then\n            ReportSuggestion \"${TEST_NO}\" \"Check your nginx error_log statements and disable debug mode\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : HTTP-6720\n    # Description : Search for nginx log files\n    if [ ${NGINX_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no HTTP-6720 --preqs-met ${PREQS_MET} --weight L --network NO --category security --description \"Check Nginx log files\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        LogText \"Test: Checking directories for files with log file definitions\"\n        for DIR in ${NGINX_CONF_LOCS}; do\n            LogText \"Test: Checking ${DIR}\"\n            if [ -d ${DIR} ]; then\n                LogText \"Result: Directory ${DIR} exists, so will be used as search path\"\n                FIND=$(find ${DIR} -type f -exec ${GREPBINARY} access_log \\{\\} \\; | ${GREPBINARY} -v \"#\" | ${AWKBINARY} '{ if($1==\"access_log\") { print $2 } }' | ${SEDBINARY} 's/;$//g' | ${SORTBINARY} -u)\n                if IsEmpty \"${FIND}\"; then\n                    LogText \"Result: no log files found\"\n                else\n                    LogText \"Result: found one or more log files\"\n                    for FILE in ${FIND}; do\n                        if [ -f ${FILE} ]; then\n                            LogText \"Found log file: ${FILE}\"\n                            Report \"log_file=${FILE}\"\n                        else\n                            LogText \"Found non existing log file: ${FILE}\"\n                        fi\n                    done\n                fi\n            else\n                LogText \"Result: directory ${DIR} not found, skipping search in this directory.\"\n            fi\n        done\n        unset DIR FILE FIND\n    fi\n#\n#################################################################################\n#\n    # Remove temp file (double check)\n    if [ -n \"${TMPFILE}\" ]; then if [ -f ${TMPFILE} ]; then rm -f ${TMPFILE}; fi; fi\n    if [ -n \"${TMPFILE2}\" ]; then if [ -f ${TMPFILE2} ]; then rm -f ${TMPFILE2}; fi; fi\n    if [ -n \"${TMPFILE3}\" ]; then if [ -f ${TMPFILE3} ]; then rm -f ${TMPFILE3}; fi; fi\n\n    WaitForKeyPress\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "include/tool_tips",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright (c) Michael Boelen, CISOfy, and many contributors.\n#\n# Website  : https://cisofy.com\n# Blog     : http://linux-audit.com\n# GitHub   : https://github.com/CISOfy/lynis\n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n#################################################################################\n#\n# Hints and Tips\n#\n#################################################################################\n#\n\n    # Only show tips when enabled\n    if [ ${SHOW_TOOL_TIPS} -eq 1 ]; then\n\n        LogText \"Tool tips: enabled\"\n        # * Regular security auditing\n        #\n        # If package is installed, then suggest users to schedule the audit daily\n        # How: confirm presence of directory /etc/lynis and check cronjobs\n\n\n        # * Check for duplicate items between default and custom profile\n        #\n        # This can be done by marking an item if it overwrites the default profile\n        # with the same value.\n        #\n        # Rationale: default profile should contain have sensible default and\n        # custom profile allows customization for the user or system.\n\n\n        # Suggest usage of plugins if none are enabled\n\n\n        # Bash completion support\n        #\n        # Detect if bash is used for active user\n        #if [ -n \"${ETC_PATHS}\" ]; then\n        #    for I in ${ETC_PATHS}; do\n        #        if [ -d ${I}/bash_completion.d ]; then\n        #            if [ ! -f ${ETC_PATHS}/bash_completion.d/lynis ]; then\n        #                Display \"This system has a bash_completion directory. Copy extras/bash_completion.d/lynis to ${I} to get completion support for Lynis\"\n        #            fi\n        #        fi\n        #    done\n        #fi\n\n    else\n        LogText \"Tool tips: enabled\"\n\n    fi\n\n\n#\n#================================================================================\n# Lynis - Security Auditing and System Hardening for Linux and UNIX - https://cisofy.com\n"
  },
  {
    "path": "lynis",
    "content": "#!/bin/sh\n\n#################################################################################\n#\n#   Lynis\n# ------------------\n#\n# Copyright Michael Boelen, CISOfy\n#\n# Web site : https://cisofy.com/\n# Blog     : https://linux-audit.com/ \n#\n# Lynis comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n# welcome to redistribute it under the terms of the GNU General Public License.\n# See LICENSE file for usage of this software.\n#\n# Lynis is licensed under GPLv3, Plugins are licensed differently (see plugins)\n#\n#################################################################################\n#\n# Lynis is an automated auditing tool for Unix based operating systems.\n#\n#################################################################################\n#\n    # In Solaris /bin/sh is not POSIX, but /usr/xpg4/bin/sh is.\n    # Switch to /usr/xpg4/bin/sh if it exists and we are not already running it.\n    if [ \"$(uname)\" = \"SunOS\" ]; then\n        test \"$_\" != \"/usr/xpg4/bin/sh\" && test -f /usr/xpg4/bin/sh && exec /usr/xpg4/bin/sh \"$0\" \"$@\"\n    fi\n#\n#################################################################################\n#\n    # Code quality: don't allow using undefined variables\n    # Notes: $_ may be empty on FreeBSD\n    set -o nounset\n#\n#################################################################################\n#\n    # Program information\n    PROGRAM_NAME=\"Lynis\"\n    PROGRAM_AUTHOR=\"CISOfy\"\n    PROGRAM_AUTHOR_CONTACT=\"lynis-dev@cisofy.com\"\n    PROGRAM_WEBSITE=\"https://cisofy.com/lynis/\"\n\n    # Version details\n    PROGRAM_RELEASE_DATE=\"2025-10-22\"\n    PROGRAM_RELEASE_TIMESTAMP=1761121526\n    PROGRAM_RELEASE_TYPE=\"release\" # pre-release or release\n    PROGRAM_VERSION=\"3.1.6\"\n\n    # Source, documentation and license\n    PROGRAM_SOURCE=\"https://github.com/CISOfy/lynis\"\n    PROGRAM_PACKAGE=\"https://packages.cisofy.com/\"\n    PROGRAM_DOCUMENTATION=\"https://cisofy.com/docs/\"\n    PROGRAM_COPYRIGHT=\"2007-2025, ${PROGRAM_AUTHOR} - ${PROGRAM_WEBSITE}\"\n    PROGRAM_LICENSE=\"${PROGRAM_NAME} comes with ABSOLUTELY NO WARRANTY. This is free software, and you are\n  welcome to redistribute it under the terms of the GNU General Public License.\n  See the LICENSE file for details about using this software.\"\n    PROGRAM_EXTRAINFO=\"Enterprise support available (compliance, plugins, interface and tools)\"\n\n    # Version number of report files (when format changes in future)\n    REPORT_version_major=\"1\"; REPORT_version_minor=\"0\"\n    REPORT_version=\"${REPORT_version_major}.${REPORT_version_minor}\"\n\n\n#\n#################################################################################\n#\n# Configure Include path and files\n#\n#################################################################################\n#\n    # Check setuid bit\n    if [ -u \"$0\" ]; then echo \"The called binary has the set-user-id bit - As this is unusual, execution will be stopped.\"; exit 1; fi\n\n    # Work directory\n    WORKDIR=$(pwd)\n\n    # Test from which directories we can use all functions and tests\n    USE_CWD=0\n    if case \"$@\" in *--usecwd*) true;; *) false;; esac; then\n        USE_CWD=1\n        INCLUDEDIR=\"./include\"\n    else\n        INCLUDEDIR=\"\"\n        tINCLUDE_TARGETS=\"/usr/local/include/lynis /usr/local/lynis/include /usr/share/lynis/include ./include\"  # Default paths to check (CWD as last option, in case we run from standalone)\n        for I in ${tINCLUDE_TARGETS}; do\n            if [ \"${I}\" = \"./include\" ]; then\n                if [ -d \"${WORKDIR}/include\" ]; then INCLUDEDIR=\"${WORKDIR}/include\"; fi\n            elif [ -d ${I} -a -z \"${INCLUDEDIR}\" ]; then\n                INCLUDEDIR=${I}\n\t\tbreak\n            fi\n        done\n    fi\n\n    # Drop out if our include directory can't be found\n    if [ -z \"${INCLUDEDIR}\" ]; then\n        printf \"%s\" \"\\nFatal error: can't find include directory\\nMake sure to execute ${PROGRAM_NAME} from untarred directory or check your installation.\"\n        exit 1\n    fi\n\n    # Test for database directory\n    if [ ${USE_CWD} -eq 1 ]; then\n        DBDIR=\"./db\"\n    else\n        DBDIR=\"\"; tDB_TARGETS=\"/usr/local/share/lynis/db /usr/local/lynis/db /usr/share/lynis/db ./db\"\n        for I in ${tDB_TARGETS}; do\n            if [ \"${I}\" = \"./db\" ]; then\n                if [ -d \"${WORKDIR}/db\" ]; then DBDIR=\"${WORKDIR}/db\"; fi\n            elif [ -d ${I} -a -z \"${DBDIR}\" ]; then\n                DBDIR=\"${I}\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n    MYID=\"\"\n    # Check user to determine file permissions later on. If we encounter Solaris, use related id binary instead\n    if [ -x /usr/xpg4/bin/id ]; then\n        MYID=$(/usr/xpg4/bin/id -u 2> /dev/null)\n    elif [ \"$(uname)\" = \"SunOS\" ]; then\n        MYID=$(id | tr '=' ' ' | tr '(' ' ' | awk '{ print $2 }' 2> /dev/null)\n    else\n        MYID=$(id -u 2> /dev/null)\n    fi\n    if [ -z \"${MYID}\" ]; then Display \"Could not find user ID with id command. Want to help improve Lynis? Raise a ticket at ${PROGRAM_SOURCE}\"; ExitFatal; fi\n#\n#################################################################################\n#\n# Set basic values and test permissions of the files to include, such as:\n# - consts: bin paths, text strings, colors\n# - functions: function library\n#\n#################################################################################\n#\n    # Determine if we are root (UID = 0)\n    if [ ${MYID} -eq 0 ]; then\n        PRIVILEGED=1\n        PENTESTINGMODE=0\n    else\n        PRIVILEGED=0\n        # Set to pentesting mode if scan is without root privileges\n        PENTESTINGMODE=1\n    fi\n\n    # Perform a basic check for permissions. After including functions, using SafePerms()\n    IGNORE_FILE_PERMISSION_ISSUES=0\n\n    FILES_TO_CHECK=\"consts functions\"\n\n    ISSUE=0\n    ISSUE_TYPE=\"\"\n    SHOWPERMERROR=0\n\n    for FILE in ${FILES_TO_CHECK}; do\n        PERMS=$(ls -l ${INCLUDEDIR}/${FILE} | cut -c 2-10)\n        GROUPPERMS=$(ls -l ${INCLUDEDIR}/${FILE} | cut -c 5-7)\n        GROUPOWNERID=$(ls -n ${INCLUDEDIR}/${FILE} | awk '{ print $4 }')\n        OWNER=$(ls -l ${INCLUDEDIR}/${FILE} | awk -F\" \" '{ print $3 }')\n        OWNERID=$(ls -n ${INCLUDEDIR}/${FILE} | awk -F\" \" '{ print $3 }')\n\n        # Check permissions of include/X file (400, 600, 640, 644)\n        if [ \"${PERMS}\" = \"rwxrwxrwx\" ]; then\n            ISSUE=1; ISSUE_TYPE=\"perms\"; echo \"[!] Change file permissions of ${INCLUDEDIR}/${FILE} to 640.\"; echo \"    Command: chmod 640 ${INCLUDEDIR}/${FILE}\"\n        elif [ ! \"${PERMS}\" = \"r--------\" -a ! \"${PERMS}\" = \"rw-------\" -a ! \"${PERMS}\" = \"rw-r-----\" -a ! \"${PERMS}\" = \"rw-r--r--\" ]; then\n            # If group ID equals user ID, we consider permissions to be fine (probably default umask)\n            if [ ! \"${GROUPOWNERID}\" = \"${OWNERID}\" ]; then\n                ISSUE=1; ISSUE_TYPE=\"perms\"; echo \"[!] Change file permissions of ${INCLUDEDIR}/${FILE} to 640.\"; echo \"    Command: chmod 640 ${INCLUDEDIR}/${FILE}\"\n            fi\n        fi\n\n        # Check if owner of both files is root user, or the same user which is running Lynis (for pentester mode)\n        if [ ! \"${OWNER}\" = \"root\" -a ! \"${OWNERID}\" = \"0\" ]; then\n            if [ ! \"${MYID}\" = \"${OWNERID}\" ]; then\n                ISSUE=1; ISSUE_TYPE=\"owner\"; SHOWPERMERROR=1; ISSUE_FILE=\"${FILE}\"; ISSUE_OWNER=\"${OWNER}\"; ISSUE_OWNERID=\"${OWNERID}\"\n            fi\n        fi\n    done\n\n    if [ ${SHOWPERMERROR} -eq 1 ]; then\n        printf \"%s\" \"\n\n[!] Change ownership of ${INCLUDEDIR}/${ISSUE_FILE} to 'root' or similar (found: ${ISSUE_OWNER} with UID ${ISSUE_OWNERID}).\n\n    Command:\n      # chown 0:0 ${INCLUDEDIR}/${ISSUE_FILE}\n\"\n    fi\n\n    # Now if there is an issue with permissions, show it to the user and let them decide how to continue.\n    if [ ${ISSUE} -eq 1 ]; then\n        printf \"\\n[X] Security check failed\\n\\n    Why do I see this error?\\n    -------------------------------\\n    This is a protection mechanism to prevent the root user from executing user created files. The files may be altered, or including malicious pieces of script.\\n\\n    What can I do?\\n    ---------------------\\n    Option 1) Check if a trusted user created the files (e.g. due to using Git, Homebrew or similar).\\n              If you trust these files, you can decide to continue this run by pressing ENTER.\\n\"\n        if [ \"${ISSUE_TYPE}\" = \"perms\" ]; then\n            printf \"\\n    Option 2) Change permissions of the related files.\\n\\n       Commands (full directory):\\n         # chmod 640 include/*\\n         # ./lynis audit system\"\n        elif [ \"${ISSUE_TYPE}\" = \"owner\" ]; then\n            printf \"\\n    Option 2) Change ownership of the related files (or full directory).\\n\\n       Commands (full directory):\\n         # cd ..\\n         # chown -R 0:0 lynis\\n         # cd lynis\\n         # ./lynis audit system\"\n        fi\n        printf \"\\n\\n[ Press ENTER to continue, or CTRL+C to cancel ]\"\n        IGNORE_FILE_PERMISSION_ISSUES=1\n        read -r void\n    fi\n\n    # Now include files if permissions are correct, or user decided to continue\n    . ${INCLUDEDIR}/consts\n    . ${INCLUDEDIR}/functions\n#\n#################################################################################\n#\n# Language settings\n#\n#################################################################################\n#\n    # Auto detection of language based on shell LANG variable. This is required by the Display() function to deal with multi-bytes characters.\n    DISPLAY_LANG=\"${LANG:-}\"\n\n    # Extract the short notation of the language (first two characters).\n    if [ -x \"$(command -v locale 2> /dev/null)\" ]; then\n        LANGUAGE=$(locale | grep -E \"^LANG=\" | cut -d= -f2 | cut -d_ -f1 | tr -d '\"' | grep -E \"^[a-z]{2}$\")\n        # Try locale command if shell variable had no value\n        if [ -z \"${DISPLAY_LANG}\" ]; then\n            DISPLAY_LANG=$(locale | grep -E \"^LANG=\" | cut -d= -f2)\n        fi\n    else\n        LANGUAGE=\"en\"\n    fi\n\n    # Set default language: 'en' (English) if no value is set\n    if [ -z \"${LANGUAGE}\" ]; then\n        LANGUAGE=\"en\"\n    fi\n\n    # Import translations. First import English to prefill all texts\n    if [ -f ${DBDIR}/languages/en ]; then\n        if SafeFile \"${DBDIR}/languages/en\"; then\n            . ${DBDIR}/languages/en\n        else\n            ExitFatal \"Incorrect ownership or permissions of language file (${DBDIR}/languages/en)\"\n        fi\n    else\n        echo \"Could not find languages directory (file: ${DBDIR}/languages/en)\"\n        exit 1\n    fi\n\n    # Now that we have determined the language, we unset it from shell\n    # Some tools with translated strings are very hard to parse\n    unset LANG\n\n#\n#################################################################################\n#\n# Traps\n#\n#################################################################################\n#\n    trap CleanUp INT TERM\n    trap Status USR1\n\n    # Use safe umask for the files we create\n    umask 027\n#\n#################################################################################\n#\n# Parameter checks\n#\n#################################################################################\n#\n    SafePerms ${INCLUDEDIR}/parameters\n    . ${INCLUDEDIR}/parameters\n\n\n    # Disable logging if no alternative was provided\n    if [ ${PRIVILEGED} -eq 0 ]; then\n        if [ -z \"${LOGFILE}\" ]; then\n            # Try creating a log file in home directory\n            if [ ! -f \"$HOME/lynis.log\" ]; then\n                if [ -L \"$HOME/lynis.log\" ]; then echo \"Log file is symlinked, which can introduce the risk of a symlink attack.\"; exit 1; fi\n                touch \"$HOME/lynis.log\"\n                if [ $? -eq 0 ]; then LOGFILE=\"$HOME/lynis.log\"; else LOGFILE=\"/dev/null\"; fi\n            else\n                LOGFILE=\"$HOME/lynis.log\"\n            fi\n        else\n            if [ -L \"${LOGFILE}\" ]; then echo \"Log file is symlinked, which can introduce the risk of a symlink attack.\"; exit 1; fi\n        fi\n        if [ -z \"${REPORTFILE}\" ]; then\n            touch \"$HOME/lynis-report.dat\"\n            if [ -L \"$HOME/lynis-report.dat\" ]; then echo \"Report file is symlinked, which can introduce the risk of a symlink attack.\"; exit 1; fi\n            if [ $? -eq 0 ]; then REPORTFILE=\"$HOME/lynis-report.dat\"; else REPORTFILE=\"/dev/null\"; fi\n        else\n            if [ -L \"${REPORTFILE}\" ]; then echo \"Report file is symlinked, which can introduce the risk of a symlink attack.\"; exit 1; fi\n        fi\n    fi\n#\n#################################################################################\n#\n# Program information\n#\n#################################################################################\n#\n    # CV - Current Version\n    PROGRAM_AC=$(echo ${PROGRAM_VERSION} | awk '{ print $1 }' | sed 's/[.]//g')\n    PROGRAM_LV=0\n#\n#################################################################################\n#\n# Initialize and default settings\n#\n#################################################################################\n#\n\n    if [ ${QUIET} -eq 0 ]; then\n        printf \"\\n${WHITE}[ ${PROGRAM_NAME} ${PROGRAM_VERSION} ]${NORMAL}\\n\\n################################################################################\\n  ${PROGRAM_LICENSE}\\n\\n  ${PROGRAM_COPYRIGHT}\\n  ${PROGRAM_EXTRAINFO}\\n################################################################################\\n\\n\"\n    fi\n\n    if [ \"${PROGRAM_RELEASE_TYPE}\" = \"beta\" ]; then\n        printf \"%s\" \"\n${WHITE}\n  #########################################################\n  #   ${YELLOW}BETA VERSION${WHITE}                                        #\n  #########################################################\n\n  Thank you for testing a beta release. Make sure to read\n  all available documentation before proceeding and/or\n  requesting support. Due the nature of beta releases, it\n  is possible new features give unexpected warnings.\n\n\n  #########################################################\n${NORMAL}\n\"\n    fi\n#\n#################################################################################\n#\n    InsertSection \"${GEN_INITIALIZE_PROGRAM}\"\n\n    # Discover any profiles\n    DiscoverProfiles\n\n    # Initialize and check profile file, auditor name, log file and report file\n    if [ -z \"${LOGDIR}\" ];            then LOGDIR=\"/var/log\"; fi\n    if [ -z \"${AUDITORNAME}\" ];       then AUDITORNAME=\"[Not Specified]\"; fi\n    if [ -z \"${LOGFILE}\" ];           then LOGFILE=\"${LOGDIR}/lynis.log\"; fi\n    if [ -z \"${REPORTFILE}\" ];        then REPORTFILE=\"${LOGDIR}/lynis-report.dat\"; fi\n#\n#################################################################################\n#\n# PID :: Check PID file, to avoid multiple instances running at the same time.\n#\n#################################################################################\n#\n    # Decide where to write our PID file. For unprivileged users this will be in their home directory, or /tmp if their\n    # home directory isn't set. For root it will be /var/run, or the current working directory if /var/run doesn't exist.\n    MYHOMEDIR=$(echo ~ 2> /dev/null)\n    if [ -z \"${MYHOMEDIR}\" ]; then MYHOMEDIR=\"/tmp\"; fi\n\n    if [ ${PRIVILEGED} -eq 0 ]; then\n        PIDFILE=\"${MYHOMEDIR}/lynis.pid\"\n    elif [ -d /var/run ]; then\n        PIDFILE=\"/var/run/lynis.pid\"\n    else\n        PIDFILE=\"./lynis.pid\"\n    fi\n\n    # Check if there is already a PID file in any of the locations (incorrect termination of previous instance)\n    if [ -f \"${MYHOMEDIR}/lynis.pid\" -o -f \"./lynis.pid\" -o -f \"/var/run/lynis.pid\" ]; then\n        printf \"%s\" \"\n\n${WARNING}Warning${NORMAL}: ${WHITE}PID file exists, probably another Lynis process is running.${NORMAL}\n------------------------------------------------------------------------------\nIf you are unsure if another Lynis process is running currently, you are advised\nto stop the current process and check the process list first. If you cancelled\na previous instance (by using CTRL+C), you can ignore this message.\n\nYou are advised to check for temporary files after program completion.\n------------------------------------------------------------------------------\n\n${YELLOW}Note: ${WHITE}Cancelling the program can leave temporary files behind${NORMAL}\n\"\n\n        # Quit directly for cron jobs.\n        if [ ${CRONJOB} -eq 1 ]; then\n            echo \"Quitting, to prevent multiple cron jobs running at the same time\"\n            exit 1 # Manually exit, no cleanups to prevent deleting an active PID file\n        else\n            WaitForKeyPress\n        fi\n\n        # Deleting any stale PID files that might exist. Note: Display function does not work yet at this point\n        if [ -f \"${MYHOMEDIR}/lynis.pid\" ]; then rm -f \"${MYHOMEDIR}/lynis.pid\"; fi\n        if [ -f \"./lynis.pid\" ]; then rm -f \"./lynis.pid\"; fi\n        if [ -f \"/var/run/lynis.pid\" ]; then rm -f \"/var/run/lynis.pid\"; fi\n    fi\n\n    # Ensure symlink attack is not possible, by confirming there is no symlink of the file already\n    OURPID=$(echo $$)\n    if [ -L ${PIDFILE} ]; then\n        echo \"Found symlinked PID file (${PIDFILE}), quitting\"\n        ExitFatal\n    else\n        # Create new PID file writable only by owner\n        echo \"${OURPID}\" > ${PIDFILE}\n        chmod 600 ${PIDFILE}\n    fi\n#\n#################################################################################\n#\n# Check program parameters\n#\n#################################################################################\n#\n    # Bail out if we didn't get any parameter, or incorrect ones\n    if [ ${PARAMCOUNT} -eq 0 -o ${WRONGOPTION} -eq 1 -o ${VIEWHELP} -eq 1 ]; then\n        printf \"%s\" \"\n\n  ${GREEN}Usage:${NORMAL} lynis ${CYAN}command ${GRAY}[options]${NORMAL}\n\n\n  ${WHITE}Command:${NORMAL}\n\n    ${CYAN}audit${NORMAL}\n        audit system                  : Perform local security scan\n        audit system remote <host>    : Remote security scan\n        audit dockerfile <file>       : Analyze Dockerfile\n\n    ${CYAN}show${NORMAL}\n        show                          : Show all commands\n        show version                  : Show ${PROGRAM_NAME} version\n        show help                     : Show help\n\n    ${CYAN}update${NORMAL}\n        update info                   : Show update details\n\n\n  ${WHITE}Options:${NORMAL}\n\n    ${WHITE}Alternative system audit modes${NORMAL}\n    ${GRAY}--forensics${NORMAL}                       : Perform forensics on a running or mounted system\n    ${GRAY}--pentest${NORMAL}                         : Non-privileged, show points of interest for pentesting\n\n    ${WHITE}Layout options${NORMAL}\n    ${GRAY}--no-colors${NORMAL}                       : Don't use colors in output\n    ${GRAY}--quiet (-q)${NORMAL}                      : No output\n    ${GRAY}--reverse-colors${NORMAL}                  : Optimize color display for light backgrounds\n    ${GRAY}--reverse-colours${NORMAL}                 : Optimize colour display for light backgrounds\n\n    ${WHITE}Misc options${NORMAL}\n    ${GRAY}--debug${NORMAL}                           : Debug logging to screen\n    ${GRAY}--no-log${NORMAL}                          : Don't create a log file\n    ${GRAY}--profile ${BROWN}<profile>${NORMAL}               : Scan the system with the given profile file\n    ${GRAY}--view-manpage (--man)${NORMAL}            : View man page\n    ${GRAY}--verbose${NORMAL}                         : Show more details on screen\n    ${GRAY}--version (-V)${NORMAL}                    : Display version number and quit\n    ${GRAY}--wait${NORMAL}                            : Wait between a set of tests\n    ${GRAY}--slow-warning ${BROWN}<seconds>${NORMAL}  : Threshold for slow test warning in seconds (default 10)\n\n    ${WHITE}Enterprise options${NORMAL}\n    ${GRAY}--plugindir ${BROWN}<path>${NORMAL}                : Define path of available plugins\n    ${GRAY}--upload${NORMAL}                          : Upload data to central node\n\n    More options available. Run '$0 show options', or use the man page.\n\n\n\"\n\n        if [ ${WRONGOPTION} -eq 1 ]; then\n            echo \"  ${RED}Error${NORMAL}: ${WHITE}Invalid option '${WRONGOPTION_value}'${NORMAL}\"\n        else\n            if [ ${VIEWHELP} -eq 0 ]; then\n                echo \"  ${RED}No command provided.${WHITE} Exiting..${NORMAL}\"\n                echo \"\"\n            fi\n        fi\n        echo \"\"\n        # Cleanup PID file if we drop out earlier\n        RemovePIDFile\n        # Exit with exit code 1\n        exit 64\n    fi\n#\n#################################################################################\n#\n    if [ ${PRIVILEGED} -eq 0 -a ${CHECK} -eq 1 -a ${QUIET} -eq 0 ]; then\n        printf \"%s\" \"${WHITE}\n  ###################################################################\n  #                                                                 #\n  #   ${PURPLE}NON-PRIVILEGED SCAN MODE${WHITE}                                      #\n  #                                                                 #\n  ###################################################################\n${NORMAL}\n  ${YELLOW}NOTES:${NORMAL}\n  --------------\n  ${WHITE}*${NORMAL} Some tests will be skipped (as they require root permissions)\n  ${WHITE}*${NORMAL} Some tests might fail silently or give different results\n\n\"\n        sleep 3\n        if [ -z \"${LOGFILE}\" -o \"${LOGFILE}\" = \"/dev/null\" ]; then\n            printf \"%s\" \"\n  ${RED}WARNING:${NORMAL}\n  ${WHITE}*${NORMAL} No suggestions or warnings will be displayed in report (due to missing log file)\"\n        fi\n    fi\n#\n#################################################################################\n#\n# OS Detection\n#\n#################################################################################\n#\n    SafePerms ${INCLUDEDIR}/osdetection\n    . ${INCLUDEDIR}/osdetection\n    Display --indent 2 --text \"- Detecting OS... \" --result \"${STATUS_DONE}\" --color GREEN\n\n    # Check hostname and get timestamp\n    case ${OS} in\n        HP-UX)\n                    HOSTNAME=$(hostname) ;;\n        Solaris)\n                    HOSTNAME=$(uname -n) ;;\n        *)\n                    HOSTNAME=$(hostname -s 2> /dev/null) ;;\n    esac\n    if [ -z \"${HOSTNAME}\" ]; then\n        HOSTNAME=$(hostname 2> /dev/null)\n        if [ -z \"${HOSTNAME}\" ]; then HOSTNAME=\"no-hostname\"; fi\n    fi\n    FQDN=$(hostname 2> /dev/null)\n    if [ \"${OS}\" = \"Linux\" -a \"${HOSTNAME}\" = \"${FQDN}\" ]; then\n        FQDN=$(hostname -f 2> /dev/null)\n    fi\n#\n#################################################################################\n#\n# Clear log and report files\n#\n#################################################################################\n#\n    # Clear log file and test if it's writable\n    CDATE=$(date \"+%Y-%m-%d %H:%M:%S\")\n    if [ ${LOGTEXT} -eq 1 ]; then echo \"${CDATE} Starting ${PROGRAM_NAME} ${PROGRAM_VERSION} with PID ${OURPID}, build date ${PROGRAM_RELEASE_DATE}\" > ${LOGFILE}; fi\n    if [ $? -gt 0 ]; then\n        Display --indent 2 --text \"- Clearing log file (${LOGFILE})... \" --result \"${STATUS_WARNING}\" --color RED\n        echo \"${WARNING}Fatal error${NORMAL}: problem while writing to log file. Check location and permissions.\"\n        RemovePIDFile\n        exit 1\n    fi\n    LogTextBreak\n    LogText \"### ${PROGRAM_COPYRIGHT} ###\"\n\n    # Clear report file (to avoid appending to an existing file)\n    if [ ${CREATE_REPORT_FILE} -eq 1 ]; then echo \"# ${PROGRAM_NAME} Report\" > ${REPORTFILE}; fi\n    Report \"report_version_major=${REPORT_version_major}\"\n    Report \"report_version_minor=${REPORT_version_minor}\"\n    CDATE=$(date \"+%F %H:%M:%S\")\n    Report \"report_datetime_start=${CDATE}\"\n    Report \"auditor=${AUDITORNAME}\"\n    Report \"lynis_version=${PROGRAM_VERSION}\"\n    Report \"os=${OS}\"\n    Report \"os_name=${OS_NAME}\"\n    Report \"os_fullname=${OS_FULLNAME}\"\n    Report \"os_version=${OS_VERSION}\"\n    if [ \"${OS}\" = \"Linux\" ]; then Report \"linux_version=${LINUX_VERSION}\"; fi\n    if [ -n \"${OS_KERNELVERSION}\" ]; then Report \"os_kernel_version=${OS_KERNELVERSION}\"; fi\n    if [ -n \"${OS_KERNELVERSION_FULL}\" ]; then Report \"os_kernel_version_full=${OS_KERNELVERSION_FULL}\"; fi\n\n    Report \"hostname=${HOSTNAME}\"\n\n    if [ -z \"${HOSTNAME}\" ]; then\n        HOSTNAME=\"no-hostname\"\n        LogText \"Info: could not find a hostname, using 'no-hostname' instead\"\n        ReportSuggestion \"LYNIS\" \"Check your hostname configuration\" \"hostname -s\"\n    fi\n    Report \"test_category=${TEST_CATEGORY_TO_CHECK}\"\n    Report \"test_group=${TEST_GROUP_TO_CHECK}\"\n\n#\n#################################################################################\n#\n# Read profile, set code checks, define language\n#\n#################################################################################\n#\n    ParseProfiles\n\n    # Define if we keep working in strict mode (development)\n    if [ ${SET_STRICT} -eq 0 ]; then\n        set +u  # Allow uninitialized variables\n    else\n        set -u  # Do not allow uninitialized variables\n    fi\n\n    # Import a different language when configured\n    if [ ! \"${LANGUAGE}\" = \"en\" ]; then\n        LogText \"Language is set to ${LANGUAGE}\"\n        Display --indent 2 --text \"- Detecting language and localization\" --result \"${LANGUAGE}\" --color WHITE\n        if [ ! -f ${DBDIR}/languages/${LANGUAGE} ]; then\n            Display --indent 4 --text \"${YELLOW}Notice:${NORMAL} no language file found for '${LANGUAGE}' (tried: ${DBDIR}/languages/${LANGUAGE})\"\n            if IsDeveloperVersion; then Display --indent 4 --text \"See https://github.com/CISOfy/lynis-sdk/blob/master/documentation/10-translations.md for more details to help translate Lynis\"; fi\n            sleep 5\n        else\n            if SafeFile \"${DBDIR}/languages/${LANGUAGE}\"; then\n                LogText \"Importing language file (${DBDIR}/languages/${LANGUAGE})\"\n                . ${DBDIR}/languages/${LANGUAGE}\n                # Check for missing translations if we are a pre-release or less than a week old\n                if grep -E -q -s \"^#\" ${DBDIR}/languages/${LANGUAGE}; then\n                    TIME_DIFFERENCE_CHECK=604800 # 1 week\n                    RELEASE_PLUS_TIMEDIFF=$((PROGRAM_RELEASE_TIMESTAMP + TIME_DIFFERENCE_CHECK))\n                    if IsDeveloperVersion || [ ${NOW} -lt ${RELEASE_PLUS_TIMEDIFF} ]; then\n                        Display --indent 4 --text \"Translation file (db/languages/${LANGUAGE}) needs an update\" --result \"OUTDATED\" --color RED\n                        Display --indent 4 --text \"=======================================================================\"\n                        Display --indent 4 --text \"Help other users and translate the missing lines:\"\n                        Display --indent 4 --text \"1) Go to: https://github.com/CISOfy/lynis/edit/master/db/languages/${LANGUAGE}\"\n                        Display --indent 4 --text \"2) Translate (some of) the lines starting with a hash (#) and remove the leading hash\"\n                        Display --indent 4 --text \"3) Commit the changes\"\n                        Display --indent 4 --text \"Thank you!\"\n                        Display --indent 4 --text \"Note: no lines with a hash? Look if the file recently has been changed by another translator.\"\n                        Display --indent 4 --text \"=======================================================================\"\n                        sleep 30\n                    fi\n                fi\n            else\n                LogText \"Could not import language file due to incorrect permissions\"\n            fi\n\n        fi\n    fi\n    LogTextBreak\n\n    # Pre-execution tests\n    if [ ${UPLOAD_DATA} -eq 1 -a -z \"${LICENSE_KEY}\" ]; then DisplayError \"${ERROR_NO_LICENSE}\" 64; fi\n    if [ ${UPLOAD_DATA} -eq 1 -a -z \"${UPLOAD_SERVER}\" ]; then DisplayError \"${ERROR_NO_UPLOAD_SERVER}\" 64; fi\n\n#\n#################################################################################\n#\n# Plugins\n#\n#################################################################################\n#\n    # Plugin directory test\n    if [ -z \"${PLUGINDIR}\" ]; then\n        #LogText \"Result: Searching for plugindir\"\n        tPLUGIN_TARGETS=\"/usr/local/lynis/plugins /usr/local/share/lynis/plugins /usr/share/lynis/plugins /etc/lynis/plugins ./plugins\"\n        for DIR in ${tPLUGIN_TARGETS}; do\n            if [ -d ${DIR} -a -z \"${PLUGINDIR}\" ]; then\n                PLUGINDIR=${DIR}\n                Debug \"Result: found plugindir ${PLUGINDIR}\"\n            fi\n        done\n    else\n        Debug \"Plugin was already set before to ${PLUGINDIR} (most likely via program argument or profile)\"\n    fi\n\n    # Drop out if our plugin directory can't be found\n    if [ -z \"${PLUGINDIR}\" -o ! -d ${PLUGINDIR} ]; then\n        echo \"Fatal error: can't find plugin directory ${PLUGINDIR}\"\n        echo \"Make sure to execute ${PROGRAM_NAME} from untarred directory or check your installation.\"\n        exit 1\n    fi\n\n#\n#################################################################################\n#\n# Show program information to display\n#\n#################################################################################\n#\n    if [ ${QUIET} -eq 0 -a ${SHOW_PROGRAM_DETAILS} -eq 1 ]; then\n        echo \"\"\n        echo \"  ---------------------------------------------------\"\n        echo \"  Program version:           ${PROGRAM_VERSION}\"\n        echo \"  Operating system:          ${OS}\"\n        echo \"  Operating system name:     ${OS_NAME}\"\n        echo \"  Operating system version:  ${OS_VERSION}\"\n        LogText \"EOL check: ${EOL}\"\n        if [ ${EOL} -eq 0 ]; then\n            echo \"  End-of-life:               ${STATUS_NO}\"\n        elif [ ${EOL} -eq 1 ]; then\n            echo \"  End-of-life:               ${WARNING}${STATUS_YES}${NORMAL}\"\n            ReportWarning \"GEN-0010\" \"This version ${OS_VERSION} is marked end-of-life as of ${EOL_DATE}\"\n        elif [ ${EOL} -eq 255 ]; then\n            echo \"  End-of-life:               ${WARNING}${STATUS_UNKNOWN}${NORMAL}\"\n            LogText \"Note: the end-of-life of '${OS_FULLNAME}' could not be checked. Entry is missing in db/software-eol.db?\"\n        fi\n\n        if [ -n \"${OS_MODE}\" ]; then echo \"  Operating system mode:     ${OS_MODE}\"; fi\n        echo \"  Kernel version:            ${OS_KERNELVERSION}\"\n        echo \"  Hardware platform:         ${HARDWARE}\"\n        echo \"  Hostname:                  ${HOSTNAME}\"\n        echo \"  ---------------------------------------------------\"\n        echo \"  Profiles:                  ${PROFILES}\"\n        echo \"  Log file:                  ${LOGFILE}\"\n        echo \"  Report file:               ${REPORTFILE}\"\n        echo \"  Report version:            ${REPORT_version}\"\n        echo \"  Plugin directory:          ${PLUGINDIR}\"\n        echo \"  ---------------------------------------------------\"\n        echo \"  Auditor:                   ${AUDITORNAME}\"\n        echo \"  Language:                  ${LANGUAGE}\"\n        echo \"  Test category:             ${TEST_CATEGORY_TO_CHECK}\"\n        echo \"  Test group:                ${TEST_GROUP_TO_CHECK}\"\n        if [ ! \"${ROOTDIR}\" = \"/\" ]; then echo \"  Root directory (custom):   ${ROOTDIR}\"; fi\n        echo \"  ---------------------------------------------------\"\n    fi\n\n    LogText \"Program version:           ${PROGRAM_VERSION}\"\n    LogText \"Operating system:          ${OS}\"\n    LogText \"Operating system name:     ${OS_NAME}\"\n    LogText \"Operating system version:  ${OS_VERSION}\"\n    if [ -n \"${OS_MODE}\" ]; then LogText \"Operating system mode:     ${OS_MODE}\"; fi\n    LogText \"Kernel version:            ${OS_KERNELVERSION}\"\n    if [ -n \"${OS_KERNELVERSION_FULL}\" ]; then\n        LogText \"Kernel version (full):     ${OS_KERNELVERSION_FULL}\"\n    fi\n    LogText \"Hardware platform:         ${HARDWARE}\"\n    LogText \"-----------------------------------------------------\"\n    LogText \"Hostname:                  ${HOSTNAME}\"\n    LogText \"Auditor:                   ${AUDITORNAME}\"\n    LogText \"Profiles:                  ${PROFILES}\"\n    LogText \"Work directory:            ${WORKDIR}\"\n    LogText \"Include directory:         ${INCLUDEDIR}\"\n    LogText \"Plugin directory:          ${PLUGINDIR}\"\n    LogText \"-----------------------------------------------------\"\n    LogText \"Log file:                  ${LOGFILE}\"\n    LogText \"Report file:               ${REPORTFILE}\"\n    LogText \"Report version:            ${REPORT_version}\"\n    LogText \"-----------------------------------------------------\"\n    LogText \"Test category:             ${TEST_CATEGORY_TO_CHECK}\"\n    LogText \"Test group:                ${TEST_GROUP_TO_CHECK}\"\n    LogText \"BusyBox used:              ${SHELL_IS_BUSYBOX}\"\n\n    Report \"plugin_directory=${PLUGINDIR}\"\n\n    LogTextBreak\n#\n#################################################################################\n#\n# Check for program update (and friendly force people to upgrade)\n#\n#################################################################################\n#\n    LogText \"Test: Checking for program update...\"\n    UPDATE_AVAILABLE=0\n\n    if [ ${SKIP_UPGRADE_TEST} -eq 1 ]; then\n        LogText \"Upgrade test skipped due profile option set (skip_upgrade_test)\"\n        PROGRAM_LV=\"${PROGRAM_AC}\"\n    else\n        CheckUpdates\n    fi\n\n    if [ -z \"${PROGRAM_AC}\" -o -z \"${PROGRAM_LV}\" ]; then\n        Display --indent 2 --text \"- Program update status... \" --result \"${STATUS_UNKNOWN}\" --color YELLOW\n        LogText \"Result: Update check failed. No network connection?\"\n        LogText \"Info: to perform an automatic update check, outbound DNS connections should be allowed (TXT record).\"\n        # Set both to safe values\n        PROGRAM_AC=0; PROGRAM_LV=0\n    else\n        LogText \"Current installed version  : ${PROGRAM_AC}\"\n        LogText \"Latest stable version      : ${PROGRAM_LV}\"\n        if [ ${PROGRAM_LV} -gt ${PROGRAM_AC} ]; then\n            # Check if current version is REALLY outdated (10 versions ago)\n            PROGRAM_MINVERSION=$((PROGRAM_LV - 10))\n            LogText \"Minimum required version   : ${PROGRAM_MINVERSION}\"\n            if [ ${PROGRAM_MINVERSION} -gt ${PROGRAM_AC} ]; then\n                Display --indent 2 --text \"- Program update status... \" --result \"${STATUS_WARNING}\" --color RED\n                LogText \"Result: This version is VERY outdated. Newer ${PROGRAM_NAME} release available!\"\n                ReportWarning \"LYNIS\" \"Version of Lynis is very old and should be updated\"\n                Report \"lynis_update_available=1\"\n                UPDATE_AVAILABLE=1\n            else\n                Display --indent 2 --text \"- Program update status... \" --result \"${STATUS_UPDATE_AVAILABLE}\" --color YELLOW\n                LogText \"Result: newer ${PROGRAM_NAME} release available!\"\n                ReportSuggestion \"LYNIS\" \"Version of Lynis outdated, consider upgrading to the latest version\"\n                Report \"lynis_update_available=1\"\n                UPDATE_AVAILABLE=1\n            fi\n        else\n            if [ ${UPDATE_CHECK_SKIPPED} -eq 0 ]; then\n                Display --indent 2 --text \"- Program update status... \" --result \"${STATUS_NO_UPDATE}\" --color GREEN\n                LogText \"No ${PROGRAM_NAME} update available.\"\n                Report \"lynis_update_available=0\"\n            else\n                Display --indent 2 --text \"- Program update status... \" --result \"${STATUS_SKIPPED}\" --color YELLOW\n                LogText \"Update check skipped due to constraints (e.g. missing dig binary)\"\n                Report \"lynis_update_available=-1\"\n            fi\n        fi\n    fi\n\n    OLD_RELEASE=0\n    TIME_DIFFERENCE_CHECK=15552000 # approx 6 months\n    RELEASE_PLUS_TIMEDIFF=$((PROGRAM_RELEASE_TIMESTAMP + TIME_DIFFERENCE_CHECK))\n    NOW=$(date \"+%s\")\n    if [ ${NOW} -gt ${RELEASE_PLUS_TIMEDIFF} ]; then\n        OLD_RELEASE=1\n    fi\n\n    # Show on screen message if there is an update available or when the release is outdated\n    # Do not show any output when quiet mode is used (--quiet/--silent)\n    if [ ${QUIET} -eq 0 ]; then\n        if [ ${UPDATE_AVAILABLE} -eq 1 ]; then\n            echo \"\"\n            echo \"      ===============================================================================\"\n            echo \"        ${CYAN}${PROGRAM_NAME} ${TEXT_UPDATE_AVAILABLE}${NORMAL}\"\n            echo \"      ===============================================================================\"\n            echo \"\"\n            if [ ${PROGRAM_LV} -gt 0 ]; then\n                echo \"        Current version : ${YELLOW}${PROGRAM_AC}${NORMAL}   Latest version : ${GREEN}${PROGRAM_LV}${NORMAL}\"\n                echo \"\"\n            fi\n            echo \"        ${WHITE}Please update to the latest version.${NORMAL}\"\n            echo \"        New releases include additional features, bug fixes, and tests.${NORMAL}\"\n        elif [ ${OLD_RELEASE} -eq 1 ]; then\n            echo \"\"\n            echo \"      ===============================================================================\"\n            echo \"        ${CYAN}${PROGRAM_NAME} might be outdated${NORMAL}\"\n            echo \"      ===============================================================================\"\n            echo \"\"\n            echo \"        ${YELLOW}Current version is more than 6 months old${NORMAL}\"\n            echo \"        This version might be ${WHITE}Please check if there is a more recent version available.${NORMAL}\"\n            echo \"\"\n            echo \"        ${WHITE}Please check if there is a more recent version available.${NORMAL}\"\n        fi\n        if [ ${OLD_RELEASE} -eq 1 -o ${UPDATE_AVAILABLE} -eq 1 ]; then\n            echo \"\"\n            echo \"        Download locations:\"\n            echo \"\"\n            echo \"        Packages (DEB/RPM) -  https://packages.cisofy.com/\"\n            echo \"        Website (TAR)      -  https://cisofy.com/downloads/\"\n            echo \"        GitHub             -  https://github.com/CISOfy/lynis\"\n            echo \"\"\n            echo \"      ===============================================================================\"\n            echo \"\"\n            sleep 5\n        fi\n    fi\n\n    LogTextBreak\n#\n#################################################################################\n#\n    # Check which binaries are available to the scanning process\n    if [ -f ${INCLUDEDIR}/binaries ]; then\n        SafePerms ${INCLUDEDIR}/binaries\n        . ${INCLUDEDIR}/binaries\n    fi\n    LogTextBreak\n#\n#################################################################################\n#\n    # Test if we have a package manager available by testing for a dummy package (should not exist)\n    if PackageIsInstalled \"__dummy__\"; then\n        HAS_PACKAGE_MANAGER=1\n        LogText \"Informational: package manager is used\"\n    else\n        LogText \"Informational: no known package manager for this system\"\n    fi\n\n    # Use hardware detection capabilities\n    IsVirtualMachine\n    if IsContainer; then\n        LogText \"Result: ${PROGRAM_NAME} is running in container (${CONTAINER_TYPE})\"\n        Report \"container=1\"\n        Report \"container_type=${CONTAINER_TYPE}\"\n    else\n        LogText \"Result: ${PROGRAM_NAME} is not running in container\"\n        Report \"container=0\"\n    fi\n    IsNotebook\n#\n#################################################################################\n#\n    # Check for systemd active\n    if [ -d /run/systemd/system ]; then\n        LogText \"Result: system is using systemd\"\n        HAS_SYSTEMD=1\n        Report \"systemd=1\"\n    else\n        LogText \"Result: systemd not found\"\n        HAS_SYSTEMD=0\n        Report \"systemd=0\"\n    fi\n#\n#################################################################################\n#\n    if IsVerbose; then\n        InsertSection \"${SECTION_PROGRAM_DETAILS}\"\n        Display --indent 2 --text \"- ${GEN_VERBOSE_MODE}\" --result \"${STATUS_YES}\" --color GREEN\n        if IsDebug; then\n            Display --indent 2 --text \"- ${GEN_DEBUG_MODE}\" --result \"${STATUS_YES}\" --color GREEN\n        else\n            Display --indent 2 --text \"- ${GEN_DEBUG_MODE}\" --result \"${STATUS_NO}\" --color RED\n        fi\n    fi\n#\n#################################################################################\n#\n    # Plugins\n    if [ ${SKIP_PLUGINS} -eq 0 ]; then\n\n        N_PLUGIN=0\n        N_PLUGIN_ENABLED=0\n\n        # Plugins function\n        RunPlugins() {\n            if [ $# -eq 0 ]; then echo \"RunPlugins should be started with phase number\"; ExitFatal; fi\n            PLUGIN_PHASE=$1\n            if [ ${PLUGIN_PHASE} -eq 0 -o ${PLUGIN_PHASE} -gt 2 ]; then echo \"Incorrect phase number when calling RunPlugins\"; ExitFatal; fi\n            LogTextBreak\n            InsertPluginSection \"Plugins (${GEN_PHASE} ${PLUGIN_PHASE})\"\n            if [ ${PLUGIN_PHASE} -eq 1 ]; then\n                Display --text \"${NOTE_PLUGINS_TAKE_TIME}\"\n                Display --text \" \"\n                LogText \"Searching plugins...\"\n            fi\n\n            # Search plugins\n            FIND_PLUGINS=$(find ${PLUGINDIR} -type f -name \"plugin_[a-z]*_phase${PLUGIN_PHASE}\" | sort)\n            for PLUGIN_FILE in ${FIND_PLUGINS}; do\n                LogText \"Found plugin file: ${PLUGIN_FILE}\"\n                # Double check if output is a valid file name\n                if [ -f ${PLUGIN_FILE} ]; then\n                    FIND2=$(grep \"^# PLUGIN_NAME=\" ${PLUGIN_FILE} | awk -F= '{ print $2 }')\n                    if [ ! \"${FIND2}\" = \"\" -a ! \"${FIND2}\" = \"[plugin_name]\" ]; then\n                        if [ ${PLUGIN_PHASE} -eq 1 ]; then N_PLUGIN=$((N_PLUGIN + 1)); fi\n                        # Check if the plugin is enabled in any of the profiles\n                        PLUGIN_ENABLED_STATE=0\n                        for PROFILE in ${PROFILES}; do\n                            LogText \"Action: checking plugin status in profile: ${PROFILE}\"\n                            FIND3=$(grep \"^plugin=${FIND2}\" ${PROFILE})\n                            if [ -n \"${FIND3}\" ]; then\n                                FOUND=0\n                                for I in ${DISABLED_PLUGINS}; do\n                                    if [ \"${I}\" = \"${FIND2}\" ]; then\n                                        FOUND=1\n                                        LogText \"Result: plugin ${FIND2} is specifically disabled\"\n                                    fi\n                                done\n                                if [ ${FOUND} -eq 0 ]; then\n                                    LogText \"Result: plugin enabled in profile (${PROFILE})\"\n                                    PLUGIN_ENABLED_STATE=1\n                                fi\n                            fi\n                        done\n                        if [ ${PLUGIN_ENABLED_STATE} -eq 1 ]; then\n                            LogText \"Result: plugin ${FIND2} is enabled\"\n                            PLUGINFILE=\"${PLUGINDIR}/plugin_${FIND2}_phase${PLUGIN_PHASE}\"\n                            if [ -f ${PLUGINFILE} ]; then\n                                PLUGIN_VERSION=$(grep \"^# PLUGIN_VERSION=\" ${PLUGIN_FILE} | awk -F= '{ print $2 }')\n                                PLUGIN_VERSION_NODOTS=$(echo ${PLUGIN_VERSION} | sed 's/.//g')\n                                if SafePerms ${PLUGINFILE}; then\n                                    LogText \"Including plugin file: ${PLUGINFILE} (version: ${PLUGIN_VERSION})\"\n                                    Report \"plugin_enabled_phase${PLUGIN_PHASE}[]=${FIND2}|${PLUGIN_VERSION}|\"\n                                    if [ ${PLUGIN_PHASE} -eq 1 ]; then N_PLUGIN_ENABLED=$((N_PLUGIN_ENABLED + 1)); fi\n                                    Display --indent 2 --text \"- ${CYAN}Plugin${NORMAL}: ${WHITE}${FIND2}${NORMAL}\"\n                                    if [ ${PLUGIN_PHASE} -eq 1 ]; then Progress \"    [\"; fi\n                                    . ${PLUGINFILE}\n                                    if [ ${PLUGIN_PHASE} -eq 1 ]; then Progress \"]\"; Progress --finish; fi\n                                    LogTextBreak\n                                    LogText \"Result: ${FIND2} plugin (phase ${PLUGIN_PHASE}) finished\"\n                                else\n                                    LogText \"Plugin ${FIND2}: Skipped (bad file permissions, should be 644, 640, 600 or 400)\"\n                                fi\n                            else\n                                LogText \"Plugin ${FIND2}: Skipped for phase ${PLUGIN_PHASE} (no file found: ${PLUGINFILE})\"\n                            fi\n                        else\n                            LogText \"Plugin ${FIND2}: Skipped (not enabled)\"\n                        fi\n                    else\n                        LogText \"Skipping plugin file ${PLUGIN_FILE} (no valid plugin name found)\"\n                    fi\n                fi\n                LogText \"--\"\n            done\n            LogText \"Result: Found ${N_PLUGIN} plugins of which ${N_PLUGIN_ENABLED} are enabled\"\n            LogText \"Result: Plugins phase ${PLUGIN_PHASE} finished\"\n        }\n        RunPlugins 1\n\n        if [ ${N_PLUGIN_ENABLED} -eq 0 ]; then\n            Display --indent 2 --text \"- ${GEN_PLUGINS_ENABLED}\" --result \"${STATUS_NONE}\" --color WHITE\n            Report \"plugins_enabled=0\"\n        else\n            Report \"plugins_enabled=1\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Get host ID\n    LogTextBreak\n    GetHostID\n    LogText \"hostid-generation: method ${HOSTID_GEN}\"\n    LogText \"hostid2-generation: method ${HOSTID2_GEN}\"\n    # Check if result is not empty (no blank, or hash of blank value, or minus, or zeros)\n    case ${HOSTID} in\n        \"\" | \"-\" | \"adc83b19e793491b1c6ea0fd8b46cd9f32e592fc\" | \"6ef1338f520d075957424741d7ed35ab5966ae97\")\n            LogText \"Info: no HostID found or invalid one\"\n        ;;\n        *)\n            LogText \"Info: HostID ${HOSTID} looks to be valid\"\n            Report \"hostid=${HOSTID}\"\n        ;;\n    esac\n\n    if [ -n \"${HOSTID2}\" ]; then\n        Report \"hostid2=${HOSTID2}\"\n    fi\n    if [ -n \"${MACHINEID}\" ]; then\n        LogText \"Info: found a machine ID ${MACHINEID}\"\n        Report \"machineid=${MACHINEID}\"\n    else\n        LogText \"Info: no machine ID found\"\n    fi\n#\n#################################################################################\n#\n\n    if [ ${RUN_TESTS} -eq 1 ]; then\n\n        LogTextBreak\n        # Test sections\n        if [ \"${TEST_GROUP_TO_CHECK}\" = \"all\" ]; then\n            LogText \"Info: perform tests from all categories\"\n\n            INCLUDE_TESTS=\"boot_services kernel memory_processes authentication kerberos shells \\\n                           filesystems usb storage storage_nfs nameservices dns ports_packages networking printers_spoolers \\\n                           mail_messaging firewalls webservers ssh snmp databases ldap php squid logging \\\n                           insecure_services banners scheduling accounting time crypto virtualization containers \\\n                           mac_frameworks file_integrity tooling malware file_permissions homedirs \\\n                           kernel_hardening hardening\"\n        else\n            INCLUDE_TESTS=\"${TEST_GROUP_TO_CHECK}\"\n            LogText \"Info: only performing tests from groups: ${TEST_GROUP_TO_CHECK}\"\n        fi\n\n        # Include available tests\n        for INCLUDE_TEST in ${INCLUDE_TESTS}; do\n            INCLUDE_FILE=\"${INCLUDEDIR}/tests_${INCLUDE_TEST}\"\n            if [ -f ${INCLUDE_FILE} ]; then\n                if SafeFile ${INCLUDE_FILE}; then\n                    . ${INCLUDE_FILE}\n                else\n                    LogText \"Exception: skipping test category ${INCLUDE_TEST}, file ${INCLUDE_FILE} has bad permissions (should be 640, 600 or 400)\"\n                    ReportWarning \"NONE\" \"Invalid permissions on tests file tests_${INCLUDE_TEST}\"\n                    # Insert a section and warn user also on screen\n                    InsertSection \"${SECTION_GENERAL}\"\n                    Display --indent 2 --text \"- Running test category ${INCLUDE_TEST}... \" --result \"${STATUS_SKIPPED}\" --color RED\n                fi\n            else\n                echo \"Error: Can't find file (category: ${INCLUDE_TEST})\"\n            fi\n        done\n    fi\n#\n#################################################################################\n#\n\n    if [ ${RUN_TESTS} -eq 1 ]; then\n\n        InsertSection \"${SECTION_CUSTOM_TESTS}\"\n        LogText \"Test: Checking for tests_custom file\"\n        # Custom tests\n        if [ -f ${INCLUDEDIR}/tests_custom ]; then\n            LogText \"Result: tests_custom file found in include directory\"\n            if SafePerms ${INCLUDEDIR}/tests_custom; then\n                Display --indent 2 --text \"- Start custom tests... \"\n                LogText \"Result: file permissions fine, running custom tests\"\n                . ${INCLUDEDIR}/tests_custom\n            else\n                LogText \"Exception: skipping custom tests, file has bad permissions (should be 640, 600 or 400)\"\n                ReportWarning \"NONE\" \"Invalid permissions on custom tests file\"\n                Display --indent 2 --text \"- Running custom tests... \" --result \"${STATUS_WARNING}\" --color RED\n            fi\n        else\n            Display --indent 2 --text \"- Running custom tests... \" --result \"${STATUS_NONE}\" --color WHITE\n        fi\n    fi\n#\n#################################################################################\n#\n# Run helpers\n#\n#################################################################################\n#\n    if [ ${RUN_HELPERS} -eq 1 ]; then\n        if [ ! \"${HELPER}\" = \"\" ]; then\n            LogText \"Helper tool is $HELPER\"\n            if [ -f ${INCLUDEDIR}/helper_${HELPER} ]; then\n                SafePerms ${INCLUDEDIR}/helper_${HELPER}\n                LogText \"Running helper tool ${HELPER} with params: ${HELPER_PARAMS}\"\n                InsertPluginSection \"Helper: ${HELPER}\"\n                . ${INCLUDEDIR}/helper_${HELPER} ${HELPER_PARAMS}\n            else\n                echo \"Error, could not find helper\"\n            fi\n        fi\n    fi\n#\n#################################################################################\n#\n# Run phase 2 of plugins\n#\n#################################################################################\n#\n    if [ ${SKIP_PLUGINS} -eq 0 ]; then\n        RunPlugins 2\n        if [ ${N_PLUGIN_ENABLED} -gt 1 ]; then\n            Display --indent 2 --text \"- Plugins (phase 2)\" --result \"${STATUS_DONE}\" --color GREEN\n        fi\n    fi\n#\n#################################################################################\n#\n# Show test results overview\n#\n#################################################################################\n#\n    # Store total performed tests\n    Report \"lynis_tests_done=${CTESTS_PERFORMED}\"\n    CDATE=$(date \"+%F %H:%M:%S\")\n    Report \"report_datetime_end=${CDATE}\"\n\n    # Show report\n    if [ -f ${INCLUDEDIR}/report ]; then SafePerms ${INCLUDEDIR}/report; . ${INCLUDEDIR}/report; fi\n\n    # Show tool tips\n    if [ -f ${INCLUDEDIR}/tool_tips ]; then SafePerms ${INCLUDEDIR}/tool_tips; . ${INCLUDEDIR}/tool_tips; fi\n\n    LogText \"================================================================================\"\n    LogText \"Tests performed:     ${CTESTS_PERFORMED}\"\n    LogText \"Total tests:         ${TOTAL_TESTS}\"\n    LogText \"Active plugins:      ${N_PLUGIN_ENABLED}\"\n    LogText \"Total plugins:       ${N_PLUGIN}\"\n    LogText \"================================================================================\"\n    Report \"tests_executed=${TESTS_EXECUTED}\"\n    Report \"tests_skipped=${TESTS_SKIPPED}\"\n    Report \"finish=true\"\n\n    # Upload data\n    if [ ${UPLOAD_DATA} -eq 1 ]; then\n        if [ -f ${INCLUDEDIR}/data_upload ]; then\n            SafePerms ${INCLUDEDIR}/data_upload\n            . ${INCLUDEDIR}/data_upload\n        else\n            echo \"Fatal error: can't find upload_data script\"\n        fi\n    fi\n\n    LogText \"${PROGRAM_NAME} ${PROGRAM_VERSION}\"\n    LogText \"${PROGRAM_COPYRIGHT}\"\n    LogText \"${PROGRAM_EXTRAINFO}\"\n    LogText \"Program ended successfully\"\n    LogText \"================================================================================\"\n\n    # Tool tips\n\n    if [ ${QUIET} -eq 0 ]; then\n\n        if [ -z \"${CUSTOM_PROFILE}\" ]; then DisplayToolTip \"Enhance ${PROGRAM_NAME} audits by adding your settings to custom.prf (see ${DEFAULT_PROFILE} for all settings)\"; fi\n    fi\n\n    # Clean exit (Delete PID file)\n    if [ ${TOTAL_WARNINGS} -gt 0 ]; then\n        # Use exit code 78 if we found any warnings (and enabled)\n        if [ ${ERROR_ON_WARNINGS} -eq 1 ]; then\n            ExitCustom 78\n        else\n            ExitClean\n        fi\n    else\n        ExitClean\n    fi\n\n    # The End\n\n#\n#================================================================================\n# Lynis - Copyright 2007-2021, Michael Boelen, CISOfy - https://cisofy.com\n"
  },
  {
    "path": "lynis.8",
    "content": ".TH Lynis 8 \"14 Feb 2020\" \"1.32\" \"Unix System Administrator's Manual\"\n\n\n.SH \"NAME\"\n\\fB\n\\fB\n\\fB\nLynis \\fP\\- System and security auditing tool\n\\fB\n.SH \"SYNOPSIS\"\n.nf\n.fam C\n\n\\fBlynis\\fP [scan mode] [other options]\n.fam T\n.fi\n.SH \"DESCRIPTION\"\n\n\\fBLynis\\fP is a security auditing tool for Linux, macOS, and other systems based\non UNIX. The tool checks the system and the software configuration, to see if\nthere is any room for improvement the security defenses. All details are stored\nin a log file. Findings and other discovered data is stored in a report file.\nThis can be used to compare differences between audits. \\fBLynis\\fP can run\ninteractively or as a cronjob. Root permissions (e.g. sudo) are not required,\nhowever provide more details during the audit.\n.PP\nThe following system areas may be checked:\n.IP\n\\- Boot loader files\n.IP\n\\- Configuration files\n.IP\n\\- Software packages\n.IP\n\\- Directories and files related to logging and auditing\n.IP\n\n.SH \"FIRST TIME USAGE\"\nWhen running \\fBLynis\\fP for the first time, run: lynis audit system\n\n.SH \"COMMANDS\"\n.IP \"audit \\<type\\>\"\nPerform an audit of the selected type\n.IP \"upload-only\"\nUpload the available report data file\n\nSee HELPERS section for more commands.\n\n.SH \"SCAN TYPES\"\n\n.IP \"audit system\"\nPerforms a system audit, which is the most common audit.\n.IP \"audit system remote \\<host\\>\"\nProvide commands to do a remote scan.\n.PP\nFor more scan modes, see the helper utilities.\n\n.SH \"OPTIONS\"\n\n.TP\n.B \\-\\-auditor <name>\nDefine the name of the auditor/pentester. When a full name is used, add double\nquotes, like \"Your Name\".\n.TP\n.B \\-\\-cronjob\nPerform automatic scan with cron safe options (no colors, no questions, no\nbreaks).\n.TP\n.B \\-\\-debug\nDisplay debug information to screen for troubleshooting purposes.\n.TP\n.B \\-\\-developer\nDisplay detailed information useful for developers when creating tests.\n.TP\n.B \\-\\-forensics\nPerform the audit on a running or mounted system (see \\-\\-rootdir)\n.TP\n.B \\-\\-help\nShow available commands and most-used options.\n.TP\n.B \\-\\-logfile </path/to/logfile>\nDefines location and name of log file, instead of default /var/log/lynis.log.\n.TP\n.B \\-\\-man\nShow the man page. Useful for systems that do not have the man page installed.\n.TP\n.B \\-\\-no\\-colors\nDisable colored output.\n.TP\n.B \\-\\-no\\-log\nRedirect all logging information to /dev/null, prevents sensitive information to\nbe written to disk.\n.TP\n.B \\-\\-no\\-plugins\nDo not run any of the enabled plugins.\n.TP\n.B \\-\\-pentest\nRun a non-privileged scan, usually used for penetration testing. Some of the\ntests will be skipped if they require root permissions.\n.TP\n.B \\-\\-plugin\\-dir </path/to/plugins>\nDefine location where plugins can be found.\n.TP\n.B \\-\\-profile <file>\nProvide alternative profile to perform the scan.\n.TP\n.B \\-\\-quick (\\-Q)\nDo a quick scan (default: don't wait for user input).\n.TP\n.B \\-\\-quiet (\\-q)\nRun quietly and do not show anything to the screen. Will also enable quick mode.\n.TP\n.B \\-\\-report\\-file <file>\nProvide an alternative name for report file.\n.TP\n.B \\-\\-reverse\\-colors\nOptimize screen output for light backgrounds.\n.TP\n.B \\-\\-tests TEST-IDs\nOnly run the specific test(s). When using multiple tests, add quotes around the\nline.\n.TP\n.B \\-\\-tests\\-from\\-category \"<category>\"\nTests are only performed if they belong to the defined category. Use the command\n\\ 'show categories' to determine all valid options.\n.TP\n.B \\-\\-tests\\-from\\-group \"<group>\"\nSimilar to \\-\\-tests\\-from\\-category. Only perform tests from a particular group.\nUse 'show groups' to determine valid options.\n.TP\n.B \\-\\-use-cwd\nRun from the current working directory.\n.TP\n.B \\-\\-upload\nUpload data to Lynis Enterprise server (profile option: upload=yes).\n.TP\n.B \\-\\-verbose\nShow more details on screen, such as components that could not found. These\ndetails are hidden by default.\n.TP\n.B \\-\\-wait\nWait for user to continue. This adds a break after each section (opposed of\n\\-\\-quick).\n.TP\n.B \\-\\-warnings\\-only\nRun quietly, except show warnings.\n.RE\n.PP\n.RS\nMultiple parameters are allowed, though some parameters can only be used together\nwith others. When running Lynis without any parameters, help will be shown and\nthe program will exit.\n.RE\n.PP\n.SH \"HELPERS\"\nLynis has special helpers to do certain tasks. This way the framework of Lynis is\nused, while at the same time storing most of the functionality in a separated\nfile. This speeds up execution and keeps the code clean.\n\n.IP \"audit\"\nRun audit on the system or on other targets\n.IP \"configure \\<parameter\\>\"\nChange or add settings to the config file\n.IP \"generate \\<parameter\\>\"\nGenerate specific details such as host IDs\n.IP \"show \\<parameter\\>\"\nShow information, such as configuration and paths\n.IP \"update \\<parameter\\>\"\nPerform activities regarding updating\n.PP\nTo use a helper, run 'lynis' followed by the helper name.\n\n.SH \"EXIT CODES\"\nLynis uses exit codes to signal any invoking script. Currently the following codes are used:\n.IP 0\nProgram exited normally\n.IP 1\nFatal error\n.IP 64\nAn unknown parameter is used, or incomplete\n.IP 65\nIncorrect data encountered\n.IP 66\nCan't open file or directory\n.IP 78\nLynis found 1 or more warnings or configurations errors (with error-on-warnings=yes)\n\n.SH \"BUGS\"\nBugs can be reported via GitHub at https://github.com/CISOfy/lynis or via support@cisofy.com\n\n.SH \"DOCUMENTATION\"\nSupporting documentation can be found via https://cisofy.com/support/\n\n.SH \"LICENSING\"\nLynis is licensed as GPLv3. The tool was created by Michael Boelen in 2007. Since 2013 its development has been taken over by CISOfy under the management of Michael Boelen. Plugins may have a different license.\n\n.SH \"CONTACT INFORMATION\"\nSupport requests and project related questions can be addressed via e-mail: lynis-dev@cisofy.com.\n"
  },
  {
    "path": "plugins/README",
    "content": "##########################################################################\n#\n# This directory contains plugins\n#\n##########################################################################\n\n\n  General notes\n  ---------------\n\n  Custom plugins should be added to this directory, so they are included\n  in an audit.\n\n  Notes:\n\n    - File permissions of a plugin should be 600, 640 or the least\n      restrictive 400.\n    - Each plugin should be enabled in the profile, before it will be\n      activated.\n    - Custom plugins should use a test ID's with a \"CUS-\" prefix.\n\n    A generic example can be found in the custom_plugin.template file,\n    which includes several code snippets to assist in creating customer\n    plugins.\n\n    Community plugins are available under a restricted license.\n\n\n**************************************************************************\n    Would your plugin or individual test benefit Lynis and others?\n   Share and be part of the Free and Open Source Software community!\n\n   Support address: lynis-dev@cisofy.com\n**************************************************************************\n"
  },
  {
    "path": "plugins/custom_plugin.template",
    "content": "#!/bin/sh\n\n# -------------------------- CUT THIS SECTION ---------------------------\n#  This is a template to create a customized plugin\n#\n#  Each plugin should at least have several variables defined with the\n#  prefix PLUGIN_* (see below)\n#\n#  If you want to learn what functions you can use, check include/functions\n#\n# -------------------------- CUT THIS SECTION ---------------------------\n\n#########################################################################\n#\n#    * DO NOT REMOVE *\n#-----------------------------------------------------\n# PLUGIN_AUTHOR=___firstname_lastname_<email>___\n# PLUGIN_CATEGORY=[category]\n# PLUGIN_DESC=[description]\n# PLUGIN_NAME=[plugin_name]\n# PLUGIN_REQUIRED_TESTS=\n#-----------------------------------------------------\n#\n#########################################################################\n#\n    # Add custom section to screen output\n    InsertSection \"Custom Plugin\"\n#\n#################################################################################\n#\n    # Test        : CUST-0001\n    # Description : We show some lines on the screen\n\n    # Register our first custom test\n    # We consider it to be a lightweight test (no heavy IO, or long searches), no network connection needed\n    Register --test-no CUST-0001 --weight L --network NO --description \"A test case for colors and text display\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        # The Display function makes it easy to show something on screen, with colors.\n        # --indent  defines amount of spaces\n        # --text    text to be displayed on screen\n        # --result  text at end of line\n        # --color   color of result text\n        Display --indent 2 --text \"- Checking if everything is OK...\" --result OK --color GREEN\n        Display --indent 4 --text \"This shows one level deeper \" --result NOTICE --color YELLOW\n        Display --indent 6 --text \"And even deeper\" --result WARNING --color RED\n\n        # Show a warning on screen and in the report. We can specify a detail and how to solve it.\n        ReportWarning \"${TEST_NO}\" \"Something was wrong and should be fixed\" \"/etc/motd\" \"text:Change your motd\"\n        ReportSuggestion \"${TEST_NO}\" \"Check if this process is running\" \"apache\" \"url:https://cisofy.com/support/\"\n    fi\n#\n#################################################################################\n#\n\n    # First check if OPENSSLBINARY is known as a prerequisite for this test.\n    if [ ! -z \"${OPENSSLBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no CUST-0001 --preqs-met ${PREQS_MET} --weight M --network NO --description \"Description of custom test\"\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUNDPROBLEM=0\n        DIR=\"/my/path\"\n        LogText \"Test: we are going to check if we can find a particular directory (${DIR})\"\n        # Check if a directory exists\n        if [ -d ${DIR} ]; then\n            LogText \"Result: log entry for easier debugging or additional information\"\n        else\n            FOUNDPROBLEM=1\n            LogText \"Result: directory ${DIR} was not found!\"\n            ReportWarning \"${TEST_NO}\" \"This is a test warning line\" \"${DIR}\" \"text:Create directory ${DIR}\"\n        fi\n\n        if [ ${FOUNDPROBLEM} -eq 0 ]; then\n            Display --indent 2 --text \"- Checking if everything is OK...\" --result OK --color GREEN\n        else\n            Display --indent 2 --text \"- Checking if everything is OK...\" --result WARNING --color RED\n            ReportSuggestion \"${TEST_NO}\" \"This is a suggestion\"\n        fi\n    fi\n#\n#################################################################################\n#\n\n# Wait for keypress (unless --quick is being used)\nWaitForKeyPress\n\n#EOF\n"
  },
  {
    "path": "plugins/plugin_pam_phase1",
    "content": "#!/bin/sh\n\n#########################################################################\n#\n#    * DO NOT REMOVE *\n#-----------------------------------------------------\n# PLUGIN_AUTHOR=Michael Boelen <michael.boelen@cisofy.com>\n# PLUGIN_CATEGORY=authentication\n# PLUGIN_DATE=2020-03-21\n# PLUGIN_DESC=PAM\n# PLUGIN_NAME=pam\n# PLUGIN_PACKAGE=all\n# PLUGIN_REQUIRED_TESTS=\n# PLUGIN_VERSION=1.0.5\n#-----------------------------------------------------\n#########################################################################\n#\n    # Variables\n    CREDITS_D_PASSWORD=\"\"\n    CREDITS_L_PASSWORD=\"\"\n    CREDITS_O_PASSWORD=\"\"\n    CREDITS_U_PASSWORD=\"\"\n    MAX_PASSWORD_RETRY=\"\"\n    MIN_PASSWORD_CLASS=\"\"\n    PAM_DIRECTORY=\"${ROOTDIR}etc/pam.d\"\n#\n#########################################################################\n#\n    # Test        : PLGN-0008\n    # Description : Check PAM configuration\n    FILE=\"${ROOTDIR}etc/security/pwquality.conf\"\n    if [ -f ${FILE} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-0008 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check PAM configuration (pwquality.conf)\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        for LINE in $(${GREPBINARY} -v \"^#\" ${FILE} | ${TRBINARY} -d \" \"); do\n            for I in ${LINE}; do\n                OPTION=$(echo ${I} | ${AWKBINARY} -F= '{ print $1 }')\n                VALUE=$(echo ${I} | ${AWKBINARY} -F= '{ print $2 }')\n                case ${OPTION} in\n                    minlen)\n                        DigitsOnly ${VALUE}\n                        MIN_PASSWORD_LENGTH=${VALUE}\n                    ;;\n                    retry)\n                        DigitsOnly ${VALUE}\n                        MAX_PASSWORD_RETRY=${VALUE}\n                    ;;\n                    minclass)\n                        MIN_PASSWORD_CLASS=${VALUE}\n                    ;;\n                    dcredit)\n                        CREDITS_D_PASSWORD=${VALUE}\n                    ;;\n                    lcredit)\n                        CREDITS_L_PASSWORD=${VALUE}\n                    ;;\n                    ocredit)\n                        CREDITS_O_PASSWORD=${VALUE}\n                    ;;\n                    ucredit)\n                        CREDITS_U_PASSWORD=${VALUE}\n                    ;;\n                esac\n            done\n        done\n    fi\n#\n#########################################################################\n#\n    # Test        : PLGN-0010\n    # Description : Check PAM configuration\n    if [ -f ${ROOTDIR}etc/pam.conf -o -d ${PAM_DIRECTORY} ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-0010 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check PAM configuration\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FOUNDPROBLEM=0\n        # Check if the PAM directory structure exists\n        if [ -d ${PAM_DIRECTORY} ]; then\n            LogText \"Result: ${PAM_DIRECTORY} exists\"\n            if [ ! \"${OS}\" = \"FreeBSD\" -a ! \"${OS}\" = \"NetBSD\" ]; then\n                FIND_FILES=$(find ${PAM_DIRECTORY} \\! -name \"*.pam-old\" -type f -print)\n            else\n                if [ -f ${PAM_DIRECTORY}/README ]; then\n                    LogText \"Skipped checking ${OS} ${PAM_DIRECTORY}/README as a PAM file\"\n                fi\n                FIND_FILES=$(find ${PAM_DIRECTORY} \\! -name \"README\" \\! -name \"*.pam-old\" -type f -print)\n            fi\n\n            for PAM_FILE in ${FIND_FILES}; do\n                LogText \"Now checking PAM file ${PAM_FILE}\"\n                while read line; do\n                    # Strip empty lines, commented lines, tabs, line breaks (\\), then finally remove all double spaces\n                    LINE=$(echo $line | grep -v \"^#\" | grep -v \"^$\" | tr '\\011' ' ' | sed 's/\\\\\\n/ /' | sed 's/  / /g' | sed 's/ #\\(.*\\)$//')\n                    if [ ! \"${LINE}\" = \"\" ]; then\n                        PAM_SERVICE=$(echo ${PAM_FILE} | awk -F/ '{ print $NF }')\n                        PAM_CONTROL_FLAG=\"-\"\n                        PAM_CONTROL_OPTIONS=\"-\"\n                        PAM_MODULE=\"-\"\n                        PAM_MODULE_OPTIONS=\"-\"\n                        PAM_TYPE=$(echo ${LINE} | awk '{ print $1 }' | sed 's/^ *-//g')\n                        PARSELINE=0\n                        case ${PAM_TYPE} in\n                            \"@include\")\n                                FILE=$(echo ${LINE} | awk '{ print $2 }')\n                                Debug \"Result: Found @include in ${PAM_FILE}. Does include PAM settings from file ${FILE} (which is individually processed)\"\n                            ;;\n                            \"account\")\n                                PARSELINE=1\n                            ;;\n                            \"auth\")\n                                PARSELINE=1\n                            ;;\n                            \"password\")\n                                PARSELINE=1\n                            ;;\n                            \"session\")\n                                PARSELINE=1\n                            ;;\n                            *)\n                                LogText \"Exception: Unknown PAM type found (${PAM_TYPE})\"\n                            ;;\n                        esac\n                        if [ ${PARSELINE} -eq 1 ]; then\n                            MULTIPLE_OPTIONS=$(echo ${LINE} | awk '$2 ~ /^\\[/')\n                            if [ ! \"${MULTIPLE_OPTIONS}\" = \"\" ]; then\n                                # Needs more parsing, depending on the options found\n                                PAM_CONTROL_OPTIONS=$(echo ${LINE} | sed \"s/^.*\\[//\" | sed \"s/\\].*$//\")\n                                LogText \"Result: Found brackets in line, indicating multiple options for control flags: ${PAM_CONTROL_OPTIONS}\"\n                                LINE=$(echo ${LINE} | sed \"s/ \\[.*\\] / other /\")\n                            fi\n                            PAM_MODULE=$(echo ${LINE} | awk '{ print $3 }')\n                            PAM_MODULE_OPTIONS=$(echo ${LINE} | cut -d ' ' -f 4-)\n                            PAM_CONTROL_FLAG=$(echo ${LINE} | awk '{ print $2 }')\n                            if [ ${PAM_CONTROL_FLAG} = \"include\" ]; then\n                                FILE=$(echo ${LINE} | awk '{ print $3 }')\n                                Debug \"Result: Found include in ${PAM_FILE}. Does include PAM settings from file ${FILE} (which is individually processed)\"\n                                PARSELINE=0\n                            fi\n                        fi\n                        if [ ${PARSELINE} -eq 1 ]; then\n                            case ${PAM_CONTROL_FLAG} in\n                                    \"optional\"|\"required\"|\"requisite\"|\"sufficient\")\n                                        #Debug \"Found a common control flag: ${PAM_CONTROL_FLAG} for ${PAM_MODULE}\"\n                                        X=0 # do nothing\n                                    ;;\n                                    \"other\")\n                                        LogText \"Result: brackets used, ignoring control flags\"\n                                    ;;\n                                    *)\n                                        LogText \"Unknown control flag found (${PAM_CONTROL_FLAG})\"\n                                    ;;\n                            esac\n                            if [ ! \"${PAM_MODULE_OPTIONS}\" = \"\" ]; then\n                                LogText \"Result: using module ${PAM_MODULE} (${PAM_CONTROL_FLAG}) with options ${PAM_MODULE_OPTIONS}\"\n                              else\n                                PAM_MODULE_OPTIONS=\"-\"\n                                LogText \"Result: using module ${PAM_MODULE} (${PAM_CONTROL_FLAG}) without options configured\"\n                            fi\n\n                            PAM_MODULE_NAME=$(echo ${PAM_MODULE} | sed 's/.so$//')\n                            #\n                            # Specific PAMs are commonly seen on these platforms:\n                            #\n                            #                     FreeBSD  Linux  macOS  NetBSD\n                            # pam_access                     v\n                            # pam_afpmount                          v\n                            # pam_afslog                                   v\n                            # pam_deny               v       v      v      v\n                            # pam_env                               v\n                            # pam_chroot             v                     v\n                            # pam_echo               v       ?             v\n                            # pam_exec               v       ?             v\n                            # pam_ftpusers                                 v\n                            # pam_group              v              v      v\n                            # pam_guest                                    v\n                            # pam_krb5               v              v      v\n                            # pam_ksu                v                     v\n                            # pam_lastlog            v                     v\n                            # pam_launchd                           v\n                            # pam_login_access       v                     v\n                            # pam_mount                             v\n                            # pam_nologin            v              v      v\n                            # pam_ntlm                              v\n                            # pam_opendirectory                     v\n                            # pam_opie               v\n                            # pam_opieaccess         v\n                            # pam_passwdqc           v\n                            # pam_permit             v              v      v\n                            # pam_radius             v                     v\n                            # pam_rhosts             v                     v\n                            # pam_rootok             v              v      v\n                            # pam_sacl                              v\n                            # pam_securetty          v              v      v\n                            # pam_securityserver                    v\n                            # pam_self               v                     v\n                            # pam_skey                                     v\n                            # pam_ssh                v                     v\n                            # pam_tacplus            v\n                            # pam_unix               v              v      v\n                            # pam_uwtmp                             v\n                            # pam_wheel                             v\n                            # pam_winbind                           v\n\n                            case ${PAM_MODULE_NAME} in\n                                pam_access) ;;\n                                pam_afpmount | pam_afslog) ;;\n                                pam_cap) ;;\n                                pam_debug | pam_deny) ;;\n                                pam_echo| pam_env | pam_exec |  pam_faildelay) ;;\n                                pam_filter | pam_ftp | pam_ftpusers) ;;\n                                # Google Authenticator / YubiKey\n                                # Common to find it only enabled for SSH\n                                pam_google_authenticator | pam_yubico)\n                                    LogText \"Result: found pam_google_authenticator\"\n                                    if [ \"${PAM_CONTROL_FLAG}\" = \"required\" ]; then\n                                        PAM_2F_AUTH_ENABLED=1\n                                        PAM_2F_AUTH_REQUIRED=1\n                                        Report \"authentication_2f_provider[]=${PAM_MODULE_NAME}\"\n                                        Report \"authentication_2f_service[]=${PAM_SERVICE}\"\n                                    elif [ \"${PAM_CONTROL_FLAG}\" = \"sufficient\" ]; then\n                                        PAM_2F_AUTH_ENABLED=1\n                                        Report \"authentication_2f_provider[]=${PAM_MODULE_NAME}\"\n                                        Report \"authentication_2f_service[]=${PAM_SERVICE}\"\n                                      else\n                                        LogText \"exception: found 2F authenticator enabled with uncommon control flag: ${PAM_CONTROL_FLAG}\"\n                                    fi\n                                ;;\n                                pam_group) ;;\n                                pam_guest) ;;\n                                pam_issue) ;;\n                                pam_keyinit | pam_krb5 | pam_ksu) ;;\n                                pam_launchd) ;;\n                                pam_lastlog | pam_limits) ;;\n                                pam_login_access) ;;\n                                # Log UID for auditd\n                                pam_loginuid)\n                                    PAM_LOGINUID_FOUND=1\n                                ;;\n                                pam_listfile | pam_localuser) ;;\n                                pam_mail | pam_mkhomedir | pam_motd) ;;\n                                pam_namespace | pam_nologin | pam_ntlm) ;;\n                                pam_opendirectory) ;;\n                                pam_permit) ;;\n\n                                # Password history - Can be configured via pam_unix or pam_pwhistory\n                                pam_pwhistory)\n                                    LogText \"Result: found ${PAM_MODULE} module (password history)\"\n                                    # set default for having pam_pwhistory enabled\n                                    PAM_PASSWORD_PWHISTORY_ENABLED=1\n                                    if [ \"${PAM_PASSWORD_PWHISTORY_AMOUNT}\" = \"\" ]; then PAM_PASSWORD_PWHISTORY_AMOUNT=10; fi\n                                    if [ ! \"${PAM_MODULE_OPTIONS}\" = \"\" ]; then\n                                        for I in ${PAM_MODULE_OPTIONS}; do\n                                            OPTION=$(echo ${I} | awk -F= '{ print $1 }')\n                                            VALUE=$(echo ${I} | awk -F= '{ print $2 }')\n                                            CREDITS_CONFIGURED=0\n                                            case ${OPTION} in\n                                                remember)\n                                                    LogText \"Result: password history (remember) configured for pam_pwhistory\"\n                                                    DigitsOnly ${VALUE}\n                                                    PAM_PASSWORD_PWHISTORY_AMOUNT=${VALUE}\n                                                    Debug \"Found password history enabled with module ${PAM_MODULE_NAME} and password amount ${PAM_PASSWORD_PWHISTORY_AMOUNT}\"\n                                                ;;\n                                            esac\n                                        done\n                                    fi\n                                ;;\n\n                                pam_radius) ;;\n                                pam_rhosts) ;;\n                                pam_rootok) ;;\n                                pam_sacl) ;;\n                                pam_securetty) ;;\n                                pam_securityserver) ;;\n                                pam_self) ;;\n                                pam_selinux) ;;\n                                pam_shells) ;;\n                                pam_skey) ;;\n                                pam_ssh)\n                                    LogText \"Result: found ${PAM_MODULE} module (SSH authentication/session management)\"\n                                    ReportWarning ${TEST_NO} \"Potential security risks using of pam_ssh(8) module.\"\n                                ;;\n                                pam_stress | pam_succeed_if | pam_systemd) ;;\n                                pam_time | pam_timestamp) ;;\n                                pam_umask) ;;\n\n                                # Password history - Can be configured via pam_unix or pam_pwhistory\n                                pam_unix)\n                                    LogText \"Result: found ${PAM_MODULE} module (generic)\"\n                                    if [ ! \"${PAM_MODULE_OPTIONS}\" = \"\" ]; then\n                                        for I in ${PAM_MODULE_OPTIONS}; do\n                                            OPTION=$(echo ${I} | awk -F= '{ print $1 }')\n                                            VALUE=$(echo ${I} | awk -F= '{ print $2 }')\n                                            CREDITS_CONFIGURED=0\n                                            case ${OPTION} in\n                                                remember)\n                                                    LogText \"Result: password history configured for pam_unix\"\n                                                    DigitsOnly ${VALUE}\n                                                    PAM_PASSWORD_UXHISTORY_AMOUNT=${VALUE}\n                                                    PAM_PASSWORD_UXHISTORY_ENABLED=1\n                                                    Debug \"Found password history enabled with module ${PAM_MODULE_NAME} and password amount ${PAM_PASSWORD_UXHISTORY_AMOUNT}\"\n                                                ;;\n                                            esac\n                                        done\n                                    fi\n                                ;;\n\n                                pam_unix_acct| pam_unix_auth | pam_unix_passwd | pam_unix_session | pam_unix2) ;;\n                                pam_uwtmp) ;;\n                                pam_vbox) ;;\n                                pam_warn | pam_wheel) ;;\n                                pam_winbind) ;;\n                                pam_xauth) ;;\n\n                                # Password strength testing\n                                pam_cracklib | pam_pwquality)\n                                    LogText \"Result: found module ${PAM_MODULE} for password strength testing\"\n\n                                    # Set default values\n                                    if [ \"${CREDITS_D_PASSWORD}\" = \"\" ]; then CREDITS_D_PASSWORD=1; fi\n                                    if [ \"${CREDITS_L_PASSWORD}\" = \"\" ]; then CREDITS_L_PASSWORD=1; fi\n                                    if [ \"${CREDITS_O_PASSWORD}\" = \"\" ]; then CREDITS_O_PASSWORD=1; fi\n                                    if [ \"${CREDITS_U_PASSWORD}\" = \"\" ]; then CREDITS_U_PASSWORD=1; fi\n                                    if [ \"${MIN_PASSWORD_CLASS}\" = \"\" ]; then MIN_PASSWORD_CLASS=0; fi\n                                    if [ \"${MIN_PASSWORD_LENGTH}\" = \"\" ]; then MIN_PASSWORD_LENGTH=6; fi\n\n                                    PAM_PASSWORD_STRENGTH_TESTED=1\n                                    if [ ! \"${PAM_MODULE_OPTIONS}\" = \"\" ]; then\n                                        Debug \"Module options configured\"\n                                        for I in ${PAM_MODULE_OPTIONS}; do\n                                            OPTION=$(echo ${I} | awk -F= '{ print $1 }')\n                                            Debug ${OPTION}\n                                            VALUE=$(echo ${I} | awk -F= '{ print $2 }')\n                                            CREDITS_CONFIGURED=0\n                                            case ${OPTION} in\n                                                minlen)\n                                                    # Minimum length (remove 1 if credits are configured, at later stage in function)\n                                                    LogText \"Result: minlen configured\"\n                                                    DigitsOnly ${VALUE}\n                                                    MIN_PASSWORD_LENGTH=${VALUE}\n                                                ;;\n                                                retry)\n                                                    # Maximum password retry\n                                                    LogText \"Result: Max password Retry configured\"\n                                                    DigitsOnly ${VALUE}\n                                                    MAX_PASSWORD_RETRY=${VALUE}\n                                                ;;\n                                                minclass)\n                                                    # Minimum number of class required out of upper, lower, digit and others\n                                                    LogText \"Result: Min number of password class is configured\"\n                                                    MIN_PASSWORD_CLASS=${VALUE}\n                                                ;;\n                                                dcredit)\n                                                    CREDITS_D_PASSWORD=${VALUE}\n                                                ;;\n                                                lcredit)\n                                                    CREDITS_L_PASSWORD=${VALUE}\n                                                ;;\n                                                ocredit)\n                                                    CREDITS_O_PASSWORD=${VALUE}\n                                                ;;\n                                                ucredit)\n                                                    CREDITS_U_PASSWORD=${VALUE}\n                                                ;;\n                                                *)\n                                                    LogText \"Result: unknown option found: ${OPTION} with value ${VALUE}\"\n                                                ;;\n                                            esac\n                                        done\n                                    fi\n                                ;;\n\n                                pam_tally | pam_tally2)\n                                    if [ \"${PAM_CONTROL_FLAG}\" = \"required\" ]; then\n                                        LogText \"Result: found a required module for countering brute force cracking attempts\"\n                                        Report \"pam_auth_brute_force_protection_module[]=${PAM_MODULE_NAME}\"\n                                        PAM_AUTH_BRUTE_FORCE_PROTECTION=1\n                                    fi\n                                    if [ ! \"${PAM_MODULE_OPTIONS}\" = \"\" ]; then\n                                        for I in ${PAM_MODULE_OPTIONS}; do\n                                            OPTION=$(echo ${I} | awk -F= '{ print $1 }')\n                                            VALUE=$(echo ${I} | awk -F= '{ print $2 }')\n                                            case ${OPTION} in\n                                                deny)\n                                                    AUTH_BLOCK_BAD_LOGIN_ATTEMPTS=\"${VALUE}\"\n                                                ;;\n                                                unlock_time)\n                                                    AUTH_UNLOCK_TIME=\"${VALUE}\"\n                                                ;;\n                                            esac\n                                        done\n                                    fi\n                                ;;\n                                \"-\")\n                                    LogText \"NOTE: this module is not parsed, as it uses an unknown control flag or type\"\n                                ;;\n                                *)\n                                    LogText \"Result: found pluggable authentication module ${PAM_MODULE}, which is unknown\"\n                                ;;\n                            esac\n                        fi\n                        #Debug \"Service:          ${PAM_SERVICE}\"\n                        #Debug \"Type:             ${PAM_TYPE}\"\n                        #Debug \"Control:          ${PAM_CONTROL_FLAG}\"\n                        #Debug \"Control options:  ${PAM_CONTROL_OPTIONS}\"\n                        #Debug \"Module:           ${PAM_MODULE_NAME}\"\n                        #Debug \"Module options:   ${PAM_MODULE_OPTIONS}\"\n                    fi\n                done < ${PAM_FILE}\n                #ParsePAMLine ${J}\n                #StoreSetting \"pam\" \"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n\n# /etc/security/opasswd should exist when:\n# password history is enabled via pam_unix\n# pam_cracklib or pam_pwquality is used\n# In that case, the file should be owned by root, with 440/640/660 permissions\n\nLogText \"[PAM] PAM 2F authentication enabled: ${PAM_2F_AUTH_ENABLED}\"\nReport \"authentication_two_factor_enabled=${PAM_2F_AUTH_ENABLED}\"\n\nLogText \"[PAM] PAM 2F authentication required: ${PAM_2F_AUTH_REQUIRED}\"\nReport \"authentication_two_factor_required=${PAM_2F_AUTH_REQUIRED}\"\n\nif [ ! \"${AUTH_UNLOCK_TIME}\" = \"-1\" ]; then\n    LogText \"[PAM] Authentication unlock time: ${AUTH_UNLOCK_TIME}\"\n    Report \"authentication_unlock_time=${AUTH_UNLOCK_TIME}\"\nelse\n    LogText \"[PAM] Authentication unlock time: not configured\"\nfi\n\nLogText \"[PAM] Password brute force protection: ${PAM_AUTH_BRUTE_FORCE_PROTECTION}\"\n\nif [ ${PAM_AUTH_BRUTE_FORCE_PROTECTION} -eq 1 ]; then\n    Report \"authentication_brute_force_protection=1\"\nfi\n\nif [ ! \"${MIN_PASSWORD_LENGTH}\" = \"-1\" ]; then\n    LogText \"[PAM] Minimum password length: ${MIN_PASSWORD_LENGTH}\"\n    Report \"minimum_password_length=${MIN_PASSWORD_LENGTH}\"\nelse\n    LogText \"[PAM] Minimum password length: not configured\"\nfi\n\nLogText \"[PAM] Password strength testing enabled: ${PAM_PASSWORD_STRENGTH_TESTED}\"\nif [ ${PAM_PASSWORD_STRENGTH_TESTED} -eq 1 ]; then\n    Report \"password_strength_tested=1\"\n\n    if [ ${CREDITS_D_PASSWORD} -ge 1 -a ${CREDITS_L_PASSWORD} -ge 1 -a ${CREDITS_O_PASSWORD} -ge 1 -a ${CREDITS_U_PASSWORD} -ge 1 ]; then\n        # Show how many password class are required out of 4\n        LogText \"[PAM] Minimum password class out of 4: ${MIN_PASSWORD_CLASS}\"\n        Report \"min_password_class=${MIN_PASSWORD_CLASS}\"\n    else\n        LogText \"[PAM] Minimum password class setting of ${MIN_PASSWORD_CLASS} out of 4 is ignored since at least 1 class are forced\"\n        Report \"min_password_class=ignored\"\n    fi\n\n    # Digits\n    if [ ${CREDITS_D_PASSWORD} -lt 0 ]; then\n        CREDITS_D_PASSWORD=$(echo ${CREDITS_D_PASSWORD} | cut -b 2-)\n        LogText \"[PAM] Minimum number of Digital characters required: ${CREDITS_D_PASSWORD}\"\n        Report \"password_min_digital_required=${CREDITS_D_PASSWORD}\"\n    elif [ ${CREDITS_D_PASSWORD} -ge 0 ]; then\n        LogText \"[PAM] Maximum credit for Digital characters: ${CREDITS_D_PASSWORD}\"\n        Report \"password_max_digital_credit=${CREDITS_D_PASSWORD}\"\n    fi\n\n    # Lowercase\n    if [ ${CREDITS_L_PASSWORD} -lt 0 ]; then\n        CREDITS_L_PASSWORD=$(echo ${CREDITS_L_PASSWORD} | cut -b 2-)\n        LogText \"[PAM] Minimum number of Lowercase characters required: ${CREDITS_L_PASSWORD}\"\n        Report \"password_min_l_required=${CREDITS_L_PASSWORD}\"\n    elif [ ${CREDITS_L_PASSWORD} -ge 0 ]; then\n        LogText \"[PAM] Maximum credit for Lowercase characters: ${CREDITS_L_PASSWORD}\"\n        Report \"password_max_l_credit=${CREDITS_L_PASSWORD}\"\n    fi\n\n    # Other characters\n    if [ ${CREDITS_O_PASSWORD} -lt 0 ]; then\n        CREDITS_O_PASSWORD=$(echo ${CREDITS_O_PASSWORD} | cut -b 2-)\n        LogText \"[PAM] Minimum number of Other characters required: ${CREDITS_O_PASSWORD}\"\n        Report \"password_min_other_required=${CREDITS_O_PASSWORD}\"\n    elif [ ${CREDITS_O_PASSWORD} -ge 0 ]; then\n        LogText \"[PAM] Maximum credit for Other characters: ${CREDITS_O_PASSWORD}\"\n        Report \"password_max_other_credit=${CREDITS_O_PASSWORD}\"\n    fi\n\n    # Uppercase\n    if [ ${CREDITS_U_PASSWORD} -lt 0 ]; then\n        CREDITS_U_PASSWORD=$(echo ${CREDITS_U_PASSWORD} | cut -b 2-)\n        LogText \"[PAM] Minimum number of Uppercase characters required: ${CREDITS_U_PASSWORD}\"\n        Report \"password_min_u_required=${CREDITS_U_PASSWORD}\"\n    elif [ ${CREDITS_U_PASSWORD} -ge 0 ]; then\n        LogText \"[PAM] Maximum credit for Uppercase characters: ${CREDITS_U_PASSWORD}\"\n        Report \"password_max_u_credit=${CREDITS_U_PASSWORD}\"\n    fi\nfi\n\n# Show how many retries are allowed to change password\nif [ ! -z \"${MAX_PASSWORD_RETRY}\" ]; then\n    LogText \"[PAM] Password maximum retry: ${MAX_PASSWORD_RETRY}\"\n    Report \"max_password_retry=${MAX_PASSWORD_RETRY}\"\nelse\n    LogText \"[PAM] Password maximum retry: Not configured\"\nfi\n\n# If auditd is running, but pam_loginuid not, events might not be properly logged\nif [ ${AUDITD_RUNNING} -eq 1 ]; then\n    if [ ${PAM_LOGINUID_FOUND} -eq 0 ]; then\n        Report \"pam_issue[]=pam_loginuid is missing\"\n    fi\nfi\n\nif [ ${PAM_PASSWORD_PWHISTORY_ENABLED} -eq 1 ]; then\n    LogText \"[PAM] Password history with pam_pwhistory enabled: ${PAM_PASSWORD_PWHISTORY_ENABLED}\"\n    LogText \"[PAM] Password history with pam_pwhistory amount: ${PAM_PASSWORD_PWHISTORY_AMOUNT}\"\n    Report \"password_history_amount=${PAM_PASSWORD_PWHISTORY_AMOUNT}\"\nelse\n    LogText \"[PAM] Password history with pam_pwhistory IS NOT enabled\"\nfi\n\nif [ ${PAM_PASSWORD_UXHISTORY_ENABLED} -eq 1 ]; then\n    LogText \"[PAM] Password history with pam_unix enabled: ${PAM_PASSWORD_UXHISTORY_ENABLED}\"\n    LogText \"[PAM] Password history with pam_unix amount: ${PAM_PASSWORD_UXHISTORY_AMOUNT}\"\n    Report \"password_history_amount=${PAM_PASSWORD_UXHISTORY_AMOUNT}\"\nelse\n    LogText \"[PAM] Password history with pam_unix IS NOT enabled\"\nfi\n\n\n\n#EOF\n"
  },
  {
    "path": "plugins/plugin_systemd_phase1",
    "content": "#!/bin/sh\n\n#########################################################################\n#\n#    * DO NOT REMOVE *\n#-----------------------------------------------------\n# PLUGIN_AUTHOR=Michael Boelen <michael.boelen@cisofy.com>\n# PLUGIN_CATEGORY=essentials\n# PLUGIN_DATE=2020-03-23\n# PLUGIN_DESC=Tests related to systemd tooling\n# PLUGIN_NAME=systemd\n# PLUGIN_PACKAGE=community\n# PLUGIN_REQUIRED_TESTS=\n# PLUGIN_VERSION=1.0.4\n#-----------------------------------------------------\n#\n#########################################################################\n#\n    SYSTEMD_COREDUMP_USED=0\n    SYSTEMD_FSS_FILE=\"\"\n    SYSTEMD_MACHINEID=\"\"\n    SYSTEMD_RUNNING=0\n    SYSTEMD_VERSION=0\n#\n#########################################################################\n#\n    # Test        : PLGN-3800\n    # Description : Gather systemctl exit code\n    if [ -n \"${SYSTEMCTLBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3800 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Gather systemctl exit code\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} > /dev/null)\n        if [ $? -gt 0 ]; then\n            Report \"systemctl_error_message=${FIND}\"\n        else\n            SYSTEMD_RUNNING=1\n        fi\n        Report \"systemctl_exit_code=$?\"\n    fi\n#\n#########################################################################\n#\n    # Test        : PLGN-3802\n    # Description : Query systemd version and options\n    # Notes       : version can also be gathered with systemctl show | grep ^Version=\n    #               features with systemctl show | grep ^Features=\n    if [ -n \"${SYSTEMCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3802 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query systemd version and options\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} --version 2> /dev/null | ${AWKBINARY} '{ if ($1==\"systemd\") { print $2 } }' | grep \"^[1-9][0-9][0-9]$\" | head -n 1)\n        if [ -n \"${FIND}\" ]; then\n            SYSTEMD_VERSION=${FIND}\n            Report \"systemd_version=${FIND}\"\n            LogText \"Result: found systemd version ${FIND}\"\n        fi\n        FIND=$(${SYSTEMCTLBINARY} --version 2> /dev/null | grep \"^[-+]\" | sed 's/[[:space:]]/,/g' | head -n 1)\n        if [ -n \"${FIND}\" ]; then\n            Report \"systemd_builtin_components=${FIND}\"\n            LogText \"Result: found builtin components list\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3804\n    # Description : Gather all systemd unit files\n    if [ -n \"${SYSTEMCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3804 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Gather systemd unit files and their status\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} --no-legend list-unit-files 2> /dev/null | ${AWKBINARY} '{ print $1\"|\"$2\"|\" }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found systemd unit files via systemctl list-unit-files\"\n            for I in ${FIND}; do\n                LogText \"Output: ${I}\"\n                Report \"systemd_unit_file[]=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3806\n    # Description : Gather all failed systemd units\n    if [ -n \"${SYSTEMCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3806 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Gather failed systemd units\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} --no-legend --state=failed 2> /dev/null | ${AWKBINARY} '{ if ($4==\"failed\" && $5==\"failed\") { print $2 } }')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found systemd unit files via systemctl list-unit-files\"\n            for I in ${FIND}; do\n                LogText \"Output: ${I}\"\n                Report \"systemd_unit_file[]=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3808\n    # Description : Gather machine ID\n    if [ -f ${ROOTDIR}etc/machine-id -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3808 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Gather systemd machine ID\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(cat ${ROOTDIR}etc/machine-id | head -n 1)\n        if [ -n \"${FIND}\" ]; then\n            SYSTEMD_MACHINEID=\"${FIND}\"\n            LogText \"Result: found machine ID: ${SYSTEMD_MACHINEID}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3810\n    # Description : Query main systemd binaries\n    if [ -n \"${FINDBINARY}\" -a -d /usr/lib/systemd -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3810 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query main systemd binaries\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${FINDBINARY} ${ROOTDIR}usr/lib/systemd -maxdepth 1 -type f -name \"systemd-*\" -printf \"%f|\")\n        if [ -n \"${FIND}\" ]; then\n            Report \"systemd_binaries=${FIND}\"\n            LogText \"Result: found systemd binaries in /usr/lib/systemd\"\n        else\n            LogText \"Result: no binaries found in /usr/lib/systemd\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3812\n    # Description : Query journal for boot related information\n    if [ -n \"${JOURNALCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 -a ${SYSTEMD_VERSION} -ge 209 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3812 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query journal for boot related information\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${JOURNALCTLBINARY} --list-boots | wc -l)\n        LogText \"Output: number of boots listed in journal is ${FIND}\"\n        if [ -n \"${FIND}\" ]; then Report \"journal_bootlogs=${FIND}\"; fi\n        FIND=$(${JOURNALCTLBINARY} --list-boots | head -n 1 | awk '{ print $4 }')\n        LogText \"Output: oldest boot date in journal is ${FIND}\"\n        if [ -n \"${FIND}\" ]; then Report \"journal_oldest_bootdate=${FIND}\"; fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3814\n    # Description : Journal integrity\n    if [ -n \"${JOURNALCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3814 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Verify journal integrity\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${JOURNALCTLBINARY} --verify 2>&1 | grep FAIL | sed 's/[[:space:]]/:space:/g')\n        if [ -n \"${FIND}\" ]; then\n            Report \"journal_contains_errors=1\"\n            for I in ${FIND}; do\n                LINE=$(echo ${I} | sed 's/:space:/ /g')\n                LogText \"Output (fails): ${LINE}\"\n            done\n          else\n            Report \"journal_contains_errors=0\"\n            LogText \"Result: systemd journal has no errors\"\n       fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3816\n    # Description : Journal sizing\n    if [ -n \"${JOURNALCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3816 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query journal for boot related information\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${JOURNALCTLBINARY} --disk-usage | awk '{ if ($1==\"Journals\") { print $4 } else if ($1==\"Archived\") { print $7 }}')\n        Report \"journal_disk_size=${FIND}\"\n        LogText \"Result: journals are ${FIND} in size\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3818\n    # Description : Journal meta data\n    if [ -n \"${JOURNALCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3818 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query journal meta data\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${JOURNALCTLBINARY} --header | sed 's/^$/|/g' | tr '\\n' ',' | sed 's/[[:space:]]//g')\n        Report \"journal_meta_data=${FIND}\"\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3820\n    # Description : Journal FSS (Forward Secure Sealing) configuration\n    if [ -n \"${JOURNALCTLBINARY}\" -a -n \"${SYSTEMD_MACHINEID}\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3820 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check for journal FSS configuration\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FILE=\"/var/log/journal/${SYSTEMD_MACHINEID}/fss\"\n        if [ -f ${FILE} ]; then\n            SYSTEMD_FSS_FILE=\"${FILE}\"\n            Report \"journal_fss=1\"\n            Report \"journal_fss_file=${SYSTEMD_FSS_FILE}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3830\n    # Description : Query systemd status\n    if [ -n \"${SYSTEMCTLBINARY}\" -a ${SYSTEMD_RUNNING} -eq 1 -a ${SYSTEMD_VERSION} -ge 215 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3830 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query systemd status\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} is-system-running 2> /dev/null | head -n 1)\n        if [ -n \"${FIND}\" ]; then\n            Report \"systemd_status=${FIND}\"\n            LogText \"Result: found systemd status = ${FIND}\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3832\n    # Description : Query processes which can not be found\n    if [ ! \"${SYSTEMCTLBINARY}\" = \"\" -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3832 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query systemd status for processes which can not be found\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} --no-legend --all --state=not-found 2> /dev/null | awk '{ print $1 }')\n        if [ -n \"${FIND}\" ]; then\n            for I in ${FIND}; do\n                Report \"systemd_unit_not_found[]=${I}\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3834\n    # Description : Gather units from systemd which can not be found\n    if [ -n \"${SYSTEMCTLBINARY}\" -a -n \"${AWKBINARY}\" ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3834 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Collect service units which can not be found in systemd\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${SYSTEMCTLBINARY} list-units -t service --all | ${AWKBINARY} '{ if ($3==\"not-found\") { print $2 }}')\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: found one or more services with faulty state\"\n            for I in ${FIND}; do\n                LogText \"Result: service seems to be faulty (not-found) ${I}\"\n                Report \"systemd_service_not_found[]=$I\"\n            done\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3856\n    # Description : Check if systemd-coredump is used\n    if [ -f /proc/sys/kernel/core_pattern -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3856 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Check if systemd-coredump is used\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        SYSTEMD_COREDUMP_USED=1\n        FIND=$(cat /proc/sys/kernel/core_pattern | grep systemd-coredump)\n        if [ -n \"${FIND}\" ]; then\n            LogText \"Result: systemd uses systemd-coredump to handle coredumps\"\n            Report \"systemd_coredump_used=1\"\n        fi\n    fi\n#\n#################################################################################\n#\n    # Test        : PLGN-3858\n    # Description : Check if coredumps are placed on disk or in the journal\n    # Notes       : systemd 215+\n#\n#################################################################################\n#\n    # Test        : PLGN-3860\n    # Description : Query coredumps from journalctl since Yesterday\n    if [ -n \"${JOURNALCTLBINARY}\" -a ${SYSTEMD_COREDUMP_USED} -eq 1 -a ${SYSTEMD_RUNNING} -eq 1 ]; then PREQS_MET=\"YES\"; else PREQS_MET=\"NO\"; fi\n    Register --test-no PLGN-3860 --preqs-met ${PREQS_MET} --weight L --network NO --description \"Query coredumps from journals since Yesterday\" --progress\n    if [ ${SKIPTEST} -eq 0 ]; then\n        FIND=$(${JOURNALCTLBINARY} SYSLOG_IDENTIFIER=systemd-coredump --since=yesterday -o cat 2> /dev/null)\n        if [ -n \"${FIND}\" ]; then\n            Report \"journal_coredumps_lastday=1\"\n            LogText \"Result: found recent coredumps\"\n        else\n            Report \"journal_coredumps_lastday=0\"\n            LogText \"Result: found no coredumps\"\n        fi\n    fi\n#\n#################################################################################\n#\n\n# coredumpctl info (systemd 215+)\n# coredumpctl -1 (systemd 215+)\n# systemd-timesyncd (systemd 213+)\n# systemctl list-machines (systemd 212+)\n# systemd-journal-remote (systemd 212+)\n# systemctl list-timers (systemd 209+)\n# systemctl cat (systemd 209+)\n\n#EOF\n"
  },
  {
    "path": "publiccode.yml",
    "content": "publiccodeYmlVersion: \"0.4\"\nname: Lynis\nurl: https://github.com/CISOfy/lynis\nreleaseDate: 2025-01-28\nplatforms:\n  - linux\n  - mac\ncategories:\n  - cloud-management\n  - compliance-management\n  - fleet-management\n  - it-management\n  - it-security\ndevelopmentStatus: stable\nsoftwareType: standalone/other\ndescription:\n  en:\n    shortDescription: Security auditing tool for Linux, macOS, and UNIX-based systems\n    longDescription: Lynis is a security auditing tool for systems based on UNIX\n      like Linux, macOS, BSD, and others. It performs an in-depth security scan\n      and runs on the system itself. The primary goal is to test security\n      defenses and provide tips for further system hardening. It will also scan\n      for general system information, vulnerable software packages, and possible\n      configuration issues. Lynis was commonly used by system administrators and\n      auditors to assess the security defenses of their systems. Besides the\n      \"blue team,\" nowadays penetration testers also have Lynis in their\n      toolkit.\n    documentation: https://cisofy.com/documentation/lynis/\n    features:\n      - command-line\n      - perform security audit\n      - extensive log\n      - security hardening advice\n      - Linux security hardening\nlegal:\n  license: AGPL-3.0-only\nmaintenance:\n  type: community\n  contacts:\n    - name: Michael Boelen\n      email: michael.boelen@cisofy.com\n      phone: \"\"\n      affiliation: \"\"\nlocalisation:\n  localisationReady: true\n  availableLanguages:\n    - en\n    - es\n    - nl\n"
  }
]